Merge "Stage all aconfig flags in setProperties path." into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index a80194c..48d6392 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -346,6 +346,12 @@
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 5772fb4..05b67ee 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -8084,7 +8084,7 @@
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 @@
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);
@@ -19675,6 +19676,7 @@
public final class CaptureRequest extends android.hardware.camera2.CameraMetadata<android.hardware.camera2.CaptureRequest.Key<?>> implements android.os.Parcelable {
method public int describeContents();
+ method @FlaggedApi("com.android.internal.camera.flags.surface_leak_fix") protected void finalize();
method @Nullable public <T> T get(android.hardware.camera2.CaptureRequest.Key<T>);
method @NonNull public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getKeys();
method @Nullable public Object getTag();
@@ -52445,8 +52447,8 @@
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();
@@ -52555,8 +52557,6 @@
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();
@@ -52641,6 +52641,8 @@
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();
@@ -52941,7 +52943,6 @@
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);
@@ -53020,6 +53021,7 @@
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);
@@ -53823,10 +53825,10 @@
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();
@@ -53849,7 +53851,6 @@
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);
@@ -53868,6 +53869,7 @@
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 b73f199..fb2a4ac 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -1306,6 +1306,7 @@
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 @@
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 @@
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 @@
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 15f1eb4..892567c6 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1624,8 +1624,6 @@
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 39823a8..fae4348 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -6054,20 +6054,6 @@
}
/**
- * 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 062b89e..e28a6ce 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -226,12 +226,6 @@
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 7c8b0fd..ef6982e 100644
--- a/core/java/android/app/DreamManager.java
+++ b/core/java/android/app/DreamManager.java
@@ -185,6 +185,22 @@
}
/**
+ * 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 7a95720..5e6b54b 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -898,10 +898,6 @@
@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 b25ebf6..620bbaf 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -14090,9 +14090,7 @@
try {
return mService.isAuditLogEnabled(mContext.getPackageName());
} catch (RemoteException re) {
- re.rethrowFromSystemServer();
- // unreachable
- return false;
+ throw re.rethrowFromSystemServer();
}
}
@@ -14102,8 +14100,8 @@
* 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 @@
@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 @@
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 @@
}
/**
- * 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 89199ca..7548562 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -1297,7 +1297,7 @@
*/
@FlaggedApi(FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION)
@Nullable
- public GetCredentialRequest getCredentialManagerRequest() {
+ public GetCredentialRequest getPendingCredentialRequest() {
return mGetCredentialRequest;
}
@@ -1306,7 +1306,7 @@
*/
@FlaggedApi(FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION)
@Nullable
- public ResultReceiver getCredentialManagerCallback() {
+ public ResultReceiver getPendingCredentialCallback() {
return mGetCredentialResultReceiver;
}
@@ -2191,14 +2191,14 @@
@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 @@
}
@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 @@
+ ", 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 a4bf985..57d958f 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 a64ee5b..8852705 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1519,6 +1519,16 @@
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 610057b..92cb9cc 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -46,6 +46,7 @@
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 {
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 {
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 faa2c70..dfb77c0 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -34,17 +34,22 @@
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 @@
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 @@
}
}
+ /** 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 @@
}
printer.println(" isPrimaryConnection: " + mIsPrimaryConnection);
printer.println(" onlyAllowReadOnlyOperations: " + mOnlyAllowReadOnlyOperations);
+ printer.println(" totalLongOperations: " + mRecentOperations.getTotalLongOperations());
mRecentOperations.dump(printer);
@@ -1595,51 +1611,39 @@
}
}
- 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 @@
}
}
}
- 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 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 @@
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 @@
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 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 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 @@
}
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 @@
}
}
+ /**
+ * 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 @@
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 ad335b6..15d7d66 100644
--- a/core/java/android/database/sqlite/SQLiteConnectionPool.java
+++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java
@@ -1175,7 +1175,7 @@
+ ", 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 7d9f02d..3b14d9d 100644
--- a/core/java/android/database/sqlite/SQLiteSession.java
+++ b/core/java/android/database/sqlite/SQLiteSession.java
@@ -312,6 +312,15 @@
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 @@
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 @@
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 3ba8be4..ff07498 100644
--- a/core/java/android/hardware/biometrics/flags.aconfig
+++ b/core/java/android/hardware/biometrics/flags.aconfig
@@ -2,6 +2,7 @@
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 {
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/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 66efccd1..c0db77c 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -309,6 +309,8 @@
private Object mUserTag;
+ private boolean mReleaseSurfaces = false;
+
/**
* Construct empty request.
*
@@ -610,6 +612,9 @@
Parcelable[] parcelableArray = in.readParcelableArray(Surface.class.getClassLoader(),
Surface.class);
if (parcelableArray != null) {
+ if (Flags.surfaceLeakFix()) {
+ mReleaseSurfaces = true;
+ }
for (Parcelable p : parcelableArray) {
Surface s = (Surface) p;
mSurfaceSet.add(s);
@@ -792,6 +797,17 @@
}
}
+ @SuppressWarnings("Finalize")
+ @FlaggedApi(Flags.FLAG_SURFACE_LEAK_FIX)
+ @Override
+ protected void finalize() {
+ if (mReleaseSurfaces) {
+ for (Surface s : mSurfaceSet) {
+ s.release();
+ }
+ }
+ }
+
/**
* A builder for capture requests.
*
diff --git a/core/java/android/hardware/camera2/extension/SessionProcessor.java b/core/java/android/hardware/camera2/extension/SessionProcessor.java
index 2e428e5..0ec5c0a 100644
--- a/core/java/android/hardware/camera2/extension/SessionProcessor.java
+++ b/core/java/android/hardware/camera2/extension/SessionProcessor.java
@@ -363,11 +363,20 @@
private final class SessionProcessorImpl extends ISessionProcessorImpl.Stub {
private long mVendorId = -1;
+ OutputSurface mImageCaptureSurface;
+ OutputSurface mPreviewSurface;
+ OutputSurface mPostviewSurface;
+
@Override
public CameraSessionConfig initSession(IBinder token, String cameraId,
Map<String, CameraMetadataNative> charsMap, OutputSurface previewSurface,
OutputSurface imageCaptureSurface, OutputSurface postviewSurface)
throws RemoteException {
+ if (Flags.surfaceLeakFix()) {
+ mPreviewSurface = previewSurface;
+ mPostviewSurface = postviewSurface;
+ mImageCaptureSurface = imageCaptureSurface;
+ }
ExtensionConfiguration config = SessionProcessor.this.initSession(token, cameraId,
new CharacteristicsMap(charsMap),
new CameraOutputSurface(previewSurface),
@@ -390,6 +399,17 @@
@Override
public void deInitSession(IBinder token) throws RemoteException {
SessionProcessor.this.deInitSession(token);
+ if (Flags.surfaceLeakFix()) {
+ if ((mPreviewSurface != null) && (mPreviewSurface.surface != null)) {
+ mPreviewSurface.surface.release();
+ }
+ if ((mImageCaptureSurface != null) && (mImageCaptureSurface.surface != null)) {
+ mImageCaptureSurface.surface.release();
+ }
+ if ((mPostviewSurface != null) && (mPostviewSurface.surface != null)) {
+ mPostviewSurface.surface.release();
+ }
+ }
}
@Override
diff --git a/core/java/android/hardware/devicestate/DeviceState.java b/core/java/android/hardware/devicestate/DeviceState.java
index e35e801..905d911 100644
--- a/core/java/android/hardware/devicestate/DeviceState.java
+++ b/core/java/android/hardware/devicestate/DeviceState.java
@@ -25,8 +25,9 @@
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.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 @@
@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 {}
- /** String description of the device state. */
+ /** @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 {}
+
@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 @@
@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 @@
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 @@
* 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 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 bc6af37..c319c89 100644
--- a/core/java/android/hardware/devicestate/DeviceStateInfo.java
+++ b/core/java/android/hardware/devicestate/DeviceStateInfo.java
@@ -24,7 +24,8 @@
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 @@
* 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 @@
* 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 @@
* 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 @@
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 @@
@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 @@
@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 @@
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 8b4d43e..a4c3833 100644
--- a/core/java/android/hardware/devicestate/DeviceStateManager.java
+++ b/core/java/android/hardware/devicestate/DeviceStateManager.java
@@ -49,7 +49,7 @@
*
* @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 6db5aee..d6cc00d 100644
--- a/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java
+++ b/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java
@@ -19,7 +19,6 @@
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 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 @@
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 @@
}
}
- // 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 @@
*
* @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 @@
}
}
- 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 @@
}
}
- return createDeviceStateList(currentInfo.supportedStates);
+ return List.copyOf(currentInfo.supportedStates);
}
}
@@ -285,13 +265,14 @@
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 @@
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 @@
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 @@
}
}
- /**
- * 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/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java
index 62473c5..4328d9f 100644
--- a/core/java/android/hardware/input/InputSettings.java
+++ b/core/java/android/hardware/input/InputSettings.java
@@ -28,6 +28,7 @@
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.TestApi;
+import android.app.AppGlobals;
import android.content.Context;
import android.os.UserHandle;
import android.provider.Settings;
@@ -393,15 +394,34 @@
*
* @hide
*/
- public static boolean isStylusPointerIconEnabled(@NonNull Context context) {
+ public static boolean isStylusPointerIconEnabled(@NonNull Context context,
+ boolean forceReloadSetting) {
if (InputProperties.force_enable_stylus_pointer_icon().orElse(false)) {
+ // Sysprop override is set
return true;
}
- return context.getResources()
- .getBoolean(com.android.internal.R.bool.config_enableStylusPointerIcon)
- && Settings.Secure.getIntForUser(context.getContentResolver(),
- Settings.Secure.STYLUS_POINTER_ICON_ENABLED,
- DEFAULT_STYLUS_POINTER_ICON_ENABLED, UserHandle.USER_CURRENT_OR_SELF) != 0;
+ if (!context.getResources().getBoolean(
+ com.android.internal.R.bool.config_enableStylusPointerIcon)) {
+ // Stylus pointer icons are disabled for the build
+ return false;
+ }
+ if (forceReloadSetting) {
+ return Settings.Secure.getIntForUser(context.getContentResolver(),
+ Settings.Secure.STYLUS_POINTER_ICON_ENABLED,
+ DEFAULT_STYLUS_POINTER_ICON_ENABLED, UserHandle.USER_CURRENT_OR_SELF) != 0;
+ }
+ return AppGlobals.getIntCoreSetting(Settings.Secure.STYLUS_POINTER_ICON_ENABLED,
+ DEFAULT_STYLUS_POINTER_ICON_ENABLED) != 0;
+ }
+
+ /**
+ * Whether a pointer icon will be shown over the location of a stylus pointer.
+ *
+ * @hide
+ * @see #isStylusPointerIconEnabled(Context, boolean)
+ */
+ public static boolean isStylusPointerIconEnabled(@NonNull Context context) {
+ return isStylusPointerIconEnabled(context, false /* forceReloadSetting */);
}
/**
diff --git a/core/java/android/net/flags.aconfig b/core/java/android/net/flags.aconfig
index 9f9aef8..3544a69 100644
--- a/core/java/android/net/flags.aconfig
+++ b/core/java/android/net/flags.aconfig
@@ -19,6 +19,7 @@
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 d679f9c..ef798ad 100644
--- a/core/java/android/net/thread/flags.aconfig
+++ b/core/java/android/net/thread/flags.aconfig
@@ -5,6 +5,7 @@
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 {
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 7afd721..97b773e 100644
--- a/core/java/android/net/vcn/flags.aconfig
+++ b/core/java/android/net/vcn/flags.aconfig
@@ -2,6 +2,7 @@
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/OWNERS b/core/java/android/os/OWNERS
index b1c24a7..90279c6 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -103,3 +103,6 @@
# ProfilingService
per-file ProfilingServiceManager.java = file:/PERFORMANCE_OWNERS
+
+# Memory
+per-file OomKillRecord.java = file:/MEMORY_OWNERS
\ No newline at end of file
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index b669814..8a17742 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -1259,6 +1259,24 @@
}
/**
+ * Reboot into recovery and wipe the data partition with ext4
+ *
+ * @throws IOException if something goes wrong.
+ *
+ * @hide
+ */
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.RECOVERY,
+ android.Manifest.permission.REBOOT
+ })
+ public void wipePartitionToExt4()
+ throws IOException {
+ // Reformat /data partition with ext4
+ String command = "--wipe_data\n--reformat_data=ext4";
+ rebootRecoveryWithCommand(command);
+ }
+
+ /**
* Reboot into the recovery system with the supplied argument.
* @param args to pass to the recovery utility.
* @throws IOException if something goes wrong.
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index c0b4909..bebb912 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -164,6 +164,8 @@
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 @@
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 d9400ac..943014c 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -3,6 +3,7 @@
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 {
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 @@
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 5e7edda..3c77c44 100644
--- a/core/java/android/security/flags.aconfig
+++ b/core/java/android/security/flags.aconfig
@@ -2,6 +2,7 @@
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 {
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 {
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 dd8b3de..09e6b5d 100644
--- a/core/java/android/service/dreams/IDreamManager.aidl
+++ b/core/java/android/service/dreams/IDreamManager.aidl
@@ -38,6 +38,8 @@
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 f9eba29..4ac78f5 100644
--- a/core/java/android/view/InsetsSource.java
+++ b/core/java/android/view/InsetsSource.java
@@ -355,11 +355,17 @@
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/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index eff35c0c0..a098e4d 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -4099,7 +4099,7 @@
* whose dataspace has RANGE_EXTENDED.
*
* @param sc The layer whose extended range brightness is being specified
- * @param currentBufferRatio The current hdr/sdr ratio of the current buffer. For example
+ * @param currentBufferRatio The current HDR/SDR ratio of the current buffer. For example
* if the buffer was rendered with a target SDR whitepoint of
* 100 nits and a max display brightness of 200 nits, this should
* be set to 2.0f.
@@ -4113,7 +4113,7 @@
*
* <p>Must be finite && >= 1.0f
*
- * @param desiredRatio The desired hdr/sdr ratio. This can be used to communicate the max
+ * @param desiredRatio The desired HDR/SDR ratio. This can be used to communicate the max
* desired brightness range. This is similar to the "max luminance"
* value in other HDR metadata formats, but represented as a ratio of
* the target SDR whitepoint to the max display brightness. The system
@@ -4150,15 +4150,15 @@
}
/**
- * Sets the desired hdr headroom for the layer.
+ * Sets the desired HDR headroom for the layer.
*
* <p>Prefer using this API over {@link #setExtendedRangeBrightness} for formats that
*. conform to HDR video standards like HLG or HDR10 which do not communicate a HDR/SDR
* ratio as part of generating the buffer.
*
- * @param sc The layer whose desired hdr headroom is being specified
+ * @param sc The layer whose desired HDR headroom is being specified
*
- * @param desiredRatio The desired hdr/sdr ratio. This can be used to communicate the max
+ * @param desiredRatio The desired HDR/SDR ratio. This can be used to communicate the max
* desired brightness range. This is similar to the "max luminance"
* value in other HDR metadata formats, but represented as a ratio of
* the target SDR whitepoint to the max display brightness. The system
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f0bde97..a5ff48f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7057,16 +7057,16 @@
/**
* 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 @@
* 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 @@
@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 @@
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 @@
// 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 @@
structure.setIsCredential(isCredential());
}
if (getViewCredentialHandler() != null) {
- structure.setCredentialManagerRequest(
+ structure.setPendingCredentialRequest(
getViewCredentialHandler().getRequest(),
getViewCredentialHandler().getCallback());
}
@@ -9995,22 +10009,22 @@
* @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 @@
* 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 @@
/**
* 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 @@
@FlaggedApi(FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION)
@Nullable
public final OutcomeReceiver<GetCredentialResponse,
- GetCredentialException> getCredentialManagerCallback() {
+ GetCredentialException> getPendingCredentialCallback() {
if (mViewCredentialHandler == null) {
return null;
}
@@ -10920,15 +10934,29 @@
}
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 @@
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 @@
/** @hide */
public boolean canNotifyAutofillEnterExitEvent() {
+ if (DBG) {
+ Log.d(VIEW_LOG_TAG, "canNotifyAutofillEnterExitEvent() entered. "
+ + " isAutofillable(): " + isAutofillable()
+ + " isAttachedToWindow(): " + isAttachedToWindow());
+ }
return isAutofillable() && isAttachedToWindow();
}
@@ -11002,7 +11042,7 @@
AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId())));
}
if (getViewCredentialHandler() != null) {
- structure.setCredentialManagerRequest(
+ structure.setPendingCredentialRequest(
getViewCredentialHandler().getRequest(),
getViewCredentialHandler().getCallback());
}
@@ -33874,7 +33914,7 @@
* - 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/ViewGroup.java b/core/java/android/view/ViewGroup.java
index fbefbf3..52ff142 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3732,6 +3732,11 @@
return afm.shouldAlwaysIncludeWebviewInAssistStructure();
}
+ private boolean shouldIncludeInvisibleView(AutofillManager afm) {
+ if (afm == null) return false;
+ return afm.shouldIncludeInvisibleViewInAssistStructure();
+ }
+
/** @hide */
private void populateChildrenForAutofill(ArrayList<View> list, @AutofillFlags int flags) {
final int childrenCount = mChildrenCount;
@@ -3754,7 +3759,7 @@
|| (shouldIncludeAllChildrenViewWithAutofillTypeNotNone(afm)
&& child.getAutofillType() != AUTOFILL_TYPE_NONE)
|| shouldIncludeAllChildrenViews(afm)
- || (Flags.includeInvisibleViewGroupInAssistStructure()
+ || (shouldIncludeInvisibleView(afm)
&& child instanceof ViewGroup && child.getVisibility() != View.VISIBLE)) {
// If the child is a ViewGroup object and its visibility is not visible, include
// it as part of the assist structure. The children of these invisible ViewGroup
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 1efd375..6c852c3 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -361,11 +361,11 @@
* {@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 @@
* {@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 @@
* @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/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index ae4a7d3..9708591 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -48,6 +48,7 @@
import android.content.res.Resources;
import android.os.Binder;
import android.os.Build;
+import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.IBinder;
@@ -67,6 +68,8 @@
import android.view.accessibility.AccessibilityEvent.EventType;
import com.android.internal.R;
+import com.android.internal.accessibility.common.ShortcutConstants;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IntPair;
@@ -78,6 +81,8 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.Executor;
/**
@@ -189,11 +194,13 @@
* <p>Note: Keep in sync with {@link #SHORTCUT_TYPES}.</p>
* @hide
*/
+ // TODO(b/323686675): reuse the one defined in ShortcutConstants
@Retention(RetentionPolicy.SOURCE)
@IntDef(value = {
// LINT.IfChange(shortcut_type_intdef)
ACCESSIBILITY_BUTTON,
- ACCESSIBILITY_SHORTCUT_KEY
+ ACCESSIBILITY_SHORTCUT_KEY,
+ UserShortcutType.QUICK_SETTINGS,
// LINT.ThenChange(:shortcut_type_array)
})
public @interface ShortcutType {}
@@ -207,6 +214,7 @@
// LINT.IfChange(shortcut_type_array)
ACCESSIBILITY_BUTTON,
ACCESSIBILITY_SHORTCUT_KEY,
+ UserShortcutType.QUICK_SETTINGS,
// LINT.ThenChange(:shortcut_type_intdef)
};
@@ -1631,6 +1639,74 @@
}
/**
+ * Turns on or off a shortcut type of the accessibility features. The shortcut type is one
+ * of the shortcut defined in the {@link ShortcutConstants.USER_SHORTCUT_TYPES}.
+ *
+ * @throws SecurityException if the app does not hold the
+ * {@link Manifest.permission#MANAGE_ACCESSIBILITY} permission
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
+ public void enableShortcutsForTargets(boolean enable,
+ @UserShortcutType int shortcutTypes, @NonNull Set<String> targets,
+ @UserIdInt int userId) {
+ final IAccessibilityManager service;
+ synchronized (mLock) {
+ service = getServiceLocked();
+ if (service == null) {
+ return;
+ }
+ }
+ try {
+ service.enableShortcutsForTargets(
+ enable, shortcutTypes, targets.stream().toList(), userId);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns accessibility feature's component and the provided tile map. This includes the
+ * TileService provided by the AccessibilityService or Accessibility Activity and the tile
+ * component provided by the framework's feature.
+ *
+ * @return a map of a feature's component name, and its provided tile's component name. The
+ * returned map's keys and values are not null. If a feature doesn't provide a tile, it won't
+ * have an entry in this map.
+ * @hide
+ * @see ShortcutConstants.A11Y_FEATURE_TO_FRAMEWORK_TILE
+ */
+ @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
+ @NonNull
+ public Map<ComponentName, ComponentName> getA11yFeatureToTileMap(@UserIdInt int userId) {
+ final IAccessibilityManager service;
+ Map<ComponentName, ComponentName> a11yFeatureToTileMap = new ArrayMap<>();
+ synchronized (mLock) {
+ service = getServiceLocked();
+ if (service == null) {
+ return a11yFeatureToTileMap;
+ }
+ }
+ try {
+ Bundle a11yFeatureToTile = service.getA11yFeatureToTileMap(userId);
+ for (String key : a11yFeatureToTile.keySet()) {
+ ComponentName feature = ComponentName.unflattenFromString(key);
+ if (feature == null) {
+ continue;
+ }
+ ComponentName tileService = a11yFeatureToTile.getParcelable(key,
+ ComponentName.class);
+ if (tileService != null) {
+ a11yFeatureToTileMap.put(feature, tileService);
+ }
+ }
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ return a11yFeatureToTileMap;
+ }
+
+ /**
* Register the provided {@link RemoteAction} with the given actionId
* <p>
* To perform established system actions, an accessibility service uses the GLOBAL_ACTION
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index 9617606..e215950 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -22,6 +22,7 @@
import android.accessibilityservice.IAccessibilityServiceClient;
import android.content.ComponentName;
import android.content.pm.ParceledListSlice;
+import android.os.Bundle;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.IAccessibilityInteractionConnection;
@@ -143,4 +144,10 @@
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE)")
oneway void notifyQuickSettingsTilesChanged(int userId, in List<ComponentName> tileComponentNames);
+
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY)")
+ oneway void enableShortcutsForTargets(boolean enable, int shortcutTypes, in List<String> shortcutTargets, int userId);
+
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY)")
+ Bundle getA11yFeatureToTileMap(int userId);
}
diff --git a/core/java/android/view/autofill/AutofillFeatureFlags.java b/core/java/android/view/autofill/AutofillFeatureFlags.java
index 334c2b77..1acfc1b 100644
--- a/core/java/android/view/autofill/AutofillFeatureFlags.java
+++ b/core/java/android/view/autofill/AutofillFeatureFlags.java
@@ -220,6 +220,19 @@
DEVICE_CONFIG_ALWAYS_INCLUDE_WEBVIEW_IN_ASSIST_STRUCTURE =
"always_include_webview_in_assist_structure";
+ /**
+ * Whether to include invisible views in the assist structure. Including invisible views can fix
+ * some cases in which Session is destroyed earlier than it is suppose to.
+ *
+ * <p>See
+ * frameworks/base/services/autofill/bugfixes.aconfig#include_invisible_view_group_in_assist_structure
+ * for more information.
+ *
+ * @hide
+ */
+ public static final String DEVICE_CONFIG_INCLUDE_INVISIBLE_VIEW_GROUP_IN_ASSIST_STRUCTURE =
+ "include_invisible_view_group_in_assist_structure";
+
// END AUTOFILL FOR ALL APPS FLAGS //
@@ -473,6 +486,13 @@
DEVICE_CONFIG_ALWAYS_INCLUDE_WEBVIEW_IN_ASSIST_STRUCTURE, true);
}
+ /** @hide */
+ public static boolean shouldIncludeInvisibleViewInAssistStructure() {
+ return DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_AUTOFILL,
+ DEVICE_CONFIG_INCLUDE_INVISIBLE_VIEW_GROUP_IN_ASSIST_STRUCTURE,
+ false);
+ }
/**
* Whether should enable multi-line filter
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 3ee8307..1484bfb 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -739,6 +739,9 @@
// Indicate whether WebView should always be included in the assist structure
private boolean mShouldAlwaysIncludeWebviewInAssistStructure;
+ // Indicate whether invisibles views should be included in the assist structure
+ private boolean mShouldIncludeInvisibleViewInAssistStructure;
+
// Controls logic around apps changing some properties of their views when activity loses
// focus due to autofill showing biometric activity, password manager, or password breach check.
private boolean mRelayoutFix;
@@ -968,6 +971,9 @@
mShouldAlwaysIncludeWebviewInAssistStructure =
AutofillFeatureFlags.shouldAlwaysIncludeWebviewInAssistStructure();
+ mShouldIncludeInvisibleViewInAssistStructure =
+ AutofillFeatureFlags.shouldIncludeInvisibleViewInAssistStructure();
+
mRelayoutFix = Flags.relayout();
mIsCredmanIntegrationEnabled = Flags.autofillCredmanIntegration();
}
@@ -1055,6 +1061,13 @@
}
/**
+ * @hide
+ */
+ public boolean shouldIncludeInvisibleViewInAssistStructure() {
+ return mShouldIncludeInvisibleViewInAssistStructure;
+ }
+
+ /**
* Get the denied or allowed activitiy names under specified package from the list string and
* set it in fields accordingly
*
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index 15b9b78..3685bba 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -1021,6 +1021,10 @@
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/java/com/android/internal/accessibility/common/ShortcutConstants.java b/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
index 7ec8838..c08968d 100644
--- a/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
+++ b/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
@@ -16,10 +16,23 @@
package com.android.internal.accessibility.common;
+import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_TILE_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_TILE_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.FONT_SIZE_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.FONT_SIZE_TILE_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.ONE_HANDED_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.ONE_HANDED_TILE_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.REDUCE_BRIGHT_COLORS_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.REDUCE_BRIGHT_COLORS_TILE_SERVICE_COMPONENT_NAME;
+
import android.annotation.IntDef;
+import android.content.ComponentName;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Map;
/**
* Collection of common constants for accessibility shortcut.
@@ -44,6 +57,10 @@
* choose accessibility shortcut as preferred shortcut.
* {@code TRIPLETAP} for displaying specifying magnification to be toggled via quickly
* tapping screen 3 times as preferred shortcut.
+ * {@code TWOFINGER_DOUBLETAP} for displaying specifying magnification to be toggled via
+ * quickly tapping screen 2 times with two fingers as preferred shortcut.
+ * {@code QUICK_SETTINGS} for displaying specifying the accessibility services or features which
+ * choose Quick Settings as preferred shortcut.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({
@@ -51,12 +68,18 @@
UserShortcutType.SOFTWARE,
UserShortcutType.HARDWARE,
UserShortcutType.TRIPLETAP,
+ UserShortcutType.TWOFINGER_DOUBLETAP,
+ UserShortcutType.QUICK_SETTINGS,
})
public @interface UserShortcutType {
int DEFAULT = 0;
- int SOFTWARE = 1; // 1 << 0
- int HARDWARE = 2; // 1 << 1
- int TRIPLETAP = 4; // 1 << 2
+ // LINT.IfChange(shortcut_type_intdef)
+ int SOFTWARE = 1 << 0;
+ int HARDWARE = 1 << 1;
+ int TRIPLETAP = 1 << 2;
+ int TWOFINGER_DOUBLETAP = 1 << 3;
+ int QUICK_SETTINGS = 1 << 4;
+ // LINT.ThenChange(:shortcut_type_array)
}
/**
@@ -64,9 +87,13 @@
* non-default IntDef types.
*/
public static final int[] USER_SHORTCUT_TYPES = {
+ // LINT.IfChange(shortcut_type_array)
UserShortcutType.SOFTWARE,
UserShortcutType.HARDWARE,
- UserShortcutType.TRIPLETAP
+ UserShortcutType.TRIPLETAP,
+ UserShortcutType.TWOFINGER_DOUBLETAP,
+ UserShortcutType.QUICK_SETTINGS,
+ // LINT.ThenChange(:shortcut_type_intdef)
};
@@ -109,4 +136,30 @@
int LAUNCH = 0;
int EDIT = 1;
}
+
+ /**
+ * Annotation for different FAB shortcut type's menu size
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ FloatingMenuSize.UNKNOWN,
+ FloatingMenuSize.SMALL,
+ FloatingMenuSize.LARGE,
+ })
+ public @interface FloatingMenuSize {
+ int UNKNOWN = -1;
+ int SMALL = 0;
+ int LARGE = 1;
+ }
+
+ /**
+ * A map of a11y feature to its qs tile component
+ */
+ public static final Map<ComponentName, ComponentName> A11Y_FEATURE_TO_FRAMEWORK_TILE = Map.of(
+ COLOR_INVERSION_COMPONENT_NAME, COLOR_INVERSION_TILE_COMPONENT_NAME,
+ DALTONIZER_COMPONENT_NAME, DALTONIZER_TILE_COMPONENT_NAME,
+ ONE_HANDED_COMPONENT_NAME, ONE_HANDED_TILE_COMPONENT_NAME,
+ REDUCE_BRIGHT_COLORS_COMPONENT_NAME, REDUCE_BRIGHT_COLORS_TILE_SERVICE_COMPONENT_NAME,
+ FONT_SIZE_COMPONENT_NAME, FONT_SIZE_TILE_COMPONENT_NAME
+ );
}
diff --git a/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java b/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
index 4f9fc39..e8472d4 100644
--- a/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
+++ b/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
@@ -70,6 +70,13 @@
public @interface A11yTextChangeType {
}
+ /** Denotes the accessibility enabled status */
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface State {
+ int OFF = 0;
+ int ON = 1;
+ }
+
/** Specifies no content has been changed for accessibility. */
public static final int NONE = 0;
/** Specifies some readable sequence has been changed. */
diff --git a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
index 3fd3030..f9c4d37 100644
--- a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
+++ b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
@@ -53,10 +53,13 @@
* Opts in component id into colon-separated {@link UserShortcutType}
* key's string from Settings.
*
- * @param context The current context.
+ * @param context The current context.
* @param shortcutType The preferred shortcut type user selected.
- * @param componentId The component id that need to be opted in Settings.
+ * @param componentId The component id that need to be opted in Settings.
+ * @deprecated Use
+ * {@link AccessibilityManager#enableShortcutsForTargets(boolean, int, Set, int)}
*/
+ @Deprecated
public static void optInValueToSettings(Context context, @UserShortcutType int shortcutType,
@NonNull String componentId) {
final StringJoiner joiner = new StringJoiner(String.valueOf(SERVICES_SEPARATOR));
@@ -83,7 +86,11 @@
* @param context The current context.
* @param shortcutType The preferred shortcut type user selected.
* @param componentId The component id that need to be opted out of Settings.
+ *
+ * @deprecated Use
+ * {@link AccessibilityManager#enableShortcutForTargets(boolean, int, Set, int)}
*/
+ @Deprecated
public static void optOutValueFromSettings(
Context context, @UserShortcutType int shortcutType, @NonNull String componentId) {
final StringJoiner joiner = new StringJoiner(String.valueOf(SERVICES_SEPARATOR));
@@ -166,6 +173,10 @@
return Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
case UserShortcutType.TRIPLETAP:
return Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED;
+ case UserShortcutType.TWOFINGER_DOUBLETAP:
+ return Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED;
+ case UserShortcutType.QUICK_SETTINGS:
+ return Settings.Secure.ACCESSIBILITY_QS_TARGETS;
default:
throw new IllegalArgumentException(
"Unsupported user shortcut type: " + type);
@@ -252,10 +263,13 @@
* If you just want to know the current state, you can use
* {@link AccessibilityManager#getAccessibilityShortcutTargets(int)}
*/
+ @NonNull
public static Set<String> getShortcutTargetsFromSettings(
Context context, @UserShortcutType int shortcutType, int userId) {
final String targetKey = convertToKey(shortcutType);
- if (Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED.equals(targetKey)) {
+ if (Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED.equals(targetKey)
+ || Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED
+ .equals(targetKey)) {
boolean magnificationEnabled = Settings.Secure.getIntForUser(
context.getContentResolver(), targetKey, /* def= */ 0, userId) == 1;
return magnificationEnabled ? Set.of(MAGNIFICATION_CONTROLLER_NAME)
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 76e7138..a0dc94f 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -93,6 +93,7 @@
shared_libs: [
"libbase",
"libcutils",
+ "libtracing_perfetto",
"libharfbuzz_ng",
"liblog",
"libminikin",
@@ -358,6 +359,7 @@
"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_Debug.cpp b/core/jni/android_os_Debug.cpp
index 1504a00..a98f947 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -410,6 +410,7 @@
stats[sub_heap].swappedOut += usage.swap;
stats[sub_heap].swappedOutPss += usage.swap_pss;
}
+ return true;
};
return meminfo::ForEachVmaFromFile(smaps_path, vma_scan);
diff --git a/core/jni/android_os_Trace.cpp b/core/jni/android_os_Trace.cpp
index ffacd9c..b579daf 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 @@
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 @@
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_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 },
+ /* name, signature, funcPtr */
+ {"nativeSetAppTracingAllowed", "(Z)V", (void*)android_os_Trace_nativeSetAppTracingAllowed},
+ {"nativeSetTracingEnabled", "(Z)V", (void*)android_os_Trace_nativeSetTracingEnabled},
- // ----------- @FastNative ----------------
+ // ----------- @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 },
+ {"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*)atrace_get_enabled_tags },
+ // ----------- @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 73877b8..09d23fa 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 e513a07..6de4a20 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 95fa5db..3e98391 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 9fb7149..0e3773b 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 5c3c652..98ec798 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 bda2a55..04b5a38 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 38b8e43..bb1b2d3 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 77933ba..b03faf7 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 b7c7399..f637f5a 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 90af630..9700fe1 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 f20d334..e56b8bc 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 d603890..0c168e5 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 fc73fa7..aa037c7 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 9faf515..9f1af24 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 983775e..bc4d929 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 7dd6a5c..969bbbf 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 58c015b..4148ad7 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 fd0cdd5..0a890b2 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 3dfadb2..5ca5236 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 6c6f1c9..edba901 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 d7af663..65e53db 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 02e29c0..a0e4a51 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 2fe8731..d6553ab 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 c28191a..bdf946e 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 7155bf4..827ddaa 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 11d5604..dca0e26 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 bec2f1f..dc030bb 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 d76b1ef..31754e4 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 6b7507a..1b99b4b 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 9f4919d..57c09da 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 6e91d3a..6bba6b0 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 4682f84..75ca762 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 bde17d0..c825bd7 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 8caacd3..1745f27 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 2020a75..af1ec29 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 f25a4b4..d921828 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 06fa36f..86640f8 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 1a609b9..d0ad38c 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 688450e..f899084 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 a1e489a..e4e6042 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 0bef068..e9d00c7 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 1f805bf..118e6e6 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 c3fab52..4331819 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 9b7556a..8975b43 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 71c128d..c8b5981 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 8c19e7b..06a572d 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 bf227d0..98bcca9 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 a575e2a..6ed95d3 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 0ff49ed..3a60709 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 a23bcfa..55633dc 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 c7f8524..a9e1c149 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 0c625c7..c20bdb0 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 9c81b79..9048ffc 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 2d603bc..32aed95 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 2ea9d40..41e217d 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 b7996f7..6f139cd 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 8b60b53..b17d7a8 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 b3e62aa..ade7c82 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 283813d..439190b 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 5e0e670..61814b7 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 3ccb86a..cf1a200 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 00d368d..9f6b733 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 3ccb86a..cf1a200 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 049ef0c..38b6e53 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 8abfb65..866f316 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 5078ee0..3668de1e 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 a10cc48..1c642f6 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 70eb803..0e72e0c 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 61d815d..caa3409 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 f0c8a20..75439d7 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 79cdce4..be777f0 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 4111f3a..65c6321 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 3d33923..b3d16d7 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 5887cd3..c8778a4 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 51ff5ae..8a05689 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 43ce6bc..3b3797a 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 1df9b8d..70ea414 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 903261c..9c7c8ef 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 bed6cf8..e60299f 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 1316898..58e576b 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 4587a62..a8d8188 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 c58c0de..b0f052e 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 b72569a..0bf9079 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 3a7de66..c15262d 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 c9dd914..91050bf 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 a0cb705..f59c099 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 4b71654..c603fa7 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 abeb08c..1f2788c 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 @@
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 @@
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 @@
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 @@
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 e118c98d..2905a5a 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.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.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 @@
}
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 936f4d7..61e05da 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceTest.java
@@ -291,6 +291,17 @@
}
@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/coretests/src/android/view/accessibility/AccessibilityManagerTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java
index e2f2554..1013bf5 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java
@@ -16,13 +16,24 @@
package android.view.accessibility;
+import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_TILE_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_TILE_COMPONENT_NAME;
+
+import static com.google.common.truth.Truth.assertThat;
+
import static junit.framework.TestCase.assertFalse;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -34,6 +45,8 @@
import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.os.RemoteException;
import android.os.UserHandle;
import androidx.annotation.NonNull;
@@ -41,6 +54,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.R;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
import com.android.internal.util.IntPair;
import com.android.server.accessibility.test.MessageCapturingHandler;
@@ -54,6 +68,8 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.Executors;
/**
@@ -263,6 +279,75 @@
verify(mMockService).unregisterProxyForDisplay(proxy.getDisplayId());
}
+ @Test
+ public void getA11yFeatureToTileMap_catchRemoteExceptionAndRethrow() throws Exception {
+ AccessibilityManager manager = createManager(WITH_A11Y_ENABLED);
+ doThrow(new RemoteException(new SecurityException()))
+ .when(mMockService)
+ .getA11yFeatureToTileMap(anyInt());
+
+ Throwable rethrownException = assertThrows(RuntimeException.class,
+ () -> manager.getA11yFeatureToTileMap(UserHandle.USER_CURRENT));
+ assertThat(rethrownException.getCause().getCause()).isInstanceOf(SecurityException.class);
+ }
+
+ @Test
+ public void getA11yFeatureToTileMap_verifyServiceMethodCalled() throws Exception {
+ AccessibilityManager manager = createManager(WITH_A11Y_ENABLED);
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(
+ COLOR_INVERSION_COMPONENT_NAME.flattenToString(),
+ COLOR_INVERSION_TILE_COMPONENT_NAME);
+ bundle.putParcelable(
+ DALTONIZER_COMPONENT_NAME.flattenToString(),
+ DALTONIZER_TILE_COMPONENT_NAME);
+ when(mMockService.getA11yFeatureToTileMap(UserHandle.USER_CURRENT)).thenReturn(bundle);
+
+ assertThat(manager.getA11yFeatureToTileMap(UserHandle.USER_CURRENT))
+ .containsExactlyEntriesIn(Map.of(
+ COLOR_INVERSION_COMPONENT_NAME, COLOR_INVERSION_TILE_COMPONENT_NAME,
+ DALTONIZER_COMPONENT_NAME, DALTONIZER_TILE_COMPONENT_NAME
+ ));
+ verify(mMockService).getA11yFeatureToTileMap(UserHandle.USER_CURRENT);
+ }
+
+ @Test
+ public void enableShortcutsForTargets_catchRemoteExceptionAndRethrow() throws Exception {
+ AccessibilityManager manager = createManager(WITH_A11Y_ENABLED);
+ doThrow(new RemoteException(new SecurityException()))
+ .when(mMockService)
+ .enableShortcutsForTargets(anyBoolean(), anyInt(), anyList(), anyInt());
+
+ Throwable rethrownException = assertThrows(RuntimeException.class,
+ () -> manager.enableShortcutsForTargets(
+ /* enable= */ false,
+ UserShortcutType.HARDWARE,
+ Set.of(DALTONIZER_COMPONENT_NAME.flattenToString()),
+ UserHandle.USER_CURRENT
+ ));
+ assertThat(rethrownException.getCause().getCause()).isInstanceOf(SecurityException.class);
+ }
+
+ @Test
+ public void enableShortcutsForTargets_verifyServiceMethodCalled() throws Exception {
+ AccessibilityManager manager = createManager(WITH_A11Y_ENABLED);
+ int shortcutTypes = UserShortcutType.HARDWARE | UserShortcutType.TRIPLETAP;
+
+ manager.enableShortcutsForTargets(
+ /* enable= */ false,
+ shortcutTypes,
+ Set.of(DALTONIZER_COMPONENT_NAME.flattenToString()),
+ UserHandle.USER_CURRENT
+ );
+
+ verify(mMockService).enableShortcutsForTargets(
+ /* enable= */ false,
+ shortcutTypes,
+ List.of(DALTONIZER_COMPONENT_NAME.flattenToString()),
+ UserHandle.USER_CURRENT
+ );
+ }
+
private class MyAccessibilityProxy extends AccessibilityDisplayProxy {
MyAccessibilityProxy(int displayId,
@NonNull List<AccessibilityServiceInfo> serviceInfos) {
diff --git a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateInfoTest.java b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateInfoTest.java
index dcef0a7..76772b7 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.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 @@
@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 @@
@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 @@
@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 @@
@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 @@
@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 @@
@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 03c38cc..ee238c0 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.runners.JUnit4;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
/**
@@ -51,8 +52,10 @@
@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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}
- 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 @@
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 @@
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 c287721..68de21f 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 @@
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();
+
+ 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_tooLargeIdentifier() {
- assertThrows(IllegalArgumentException.class,
- () -> new DeviceState(MAXIMUM_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());
- @Test
- public void testConstruct_tooSmallIdentifier() {
- assertThrows(IllegalArgumentException.class,
- () -> new DeviceState(MINIMUM_DEVICE_STATE_IDENTIFIER - 1 /* identifier */,
- null /* name */, 0 /* flags */));
+ 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 a7acaf9..a2a0f49 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -333,6 +333,11 @@
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 4e88b0e..5b1fa7b 100644
--- a/graphics/java/android/graphics/BaseRecordingCanvas.java
+++ b/graphics/java/android/graphics/BaseRecordingCanvas.java
@@ -290,6 +290,11 @@
}
@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 f9ac02a..e03a1da 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -1931,6 +1931,17 @@
}
/**
+ * 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 88fd461..fa35b63 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 @@
* 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 @@
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 b315f94..d31bf2a 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 @@
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 @@
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 @@
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 @@
@GuardedBy("mLock")
private int getCurrentRearDisplayModeStatus() {
- if (mRearDisplayState == INVALID_DEVICE_STATE) {
+ if (mRearDisplayState == INVALID_DEVICE_STATE_IDENTIFIER) {
return WindowAreaComponent.STATUS_UNSUPPORTED;
}
@@ -495,7 +495,7 @@
@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 @@
@GuardedBy("mLock")
private int getCurrentRearDisplayPresentationModeStatus() {
- if (mConcurrentDisplayState == INVALID_DEVICE_STATE) {
+ if (mConcurrentDisplayState == INVALID_DEVICE_STATE_IDENTIFIER) {
return WindowAreaComponent.STATUS_UNSUPPORTED;
}
@@ -530,7 +530,7 @@
@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 a883e08..b54f9cf 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 a541c59..c68b0be 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 474430e..23bdd08 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 @@
// 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 @@
}
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 8a33780..4175529 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 @@
* @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 @@
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 e43609f..aa4129a 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.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 @@
}
@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 @@
}
@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 4c0281d..e261d92 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.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 @@
@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 @@
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 7b84868..494d893 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 @@
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 @@
}
/**
- * Return whether the display size restrictions should be enforced.
+ * Return {@code true} if desktop mode should be restricted to supported devices.
*/
- public static boolean enforceDisplayRestrictions() {
- return ENFORCE_DISPLAY_RESTRICTIONS;
+ @VisibleForTesting
+ public static boolean enforceDeviceRestrictions() {
+ return ENFORCE_DEVICE_RESTRICTIONS;
}
/**
- * 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 the current device supports desktop mode.
*/
- public static boolean meetsMinimumDisplayRequirements(@NonNull RunningTaskInfo taskInfo) {
- return !enforceDisplayRestrictions()
- || taskInfo.configuration.isLayoutSizeAtLeast(SCREENLAYOUT_SIZE_XLARGE);
+ @VisibleForTesting
+ public static boolean isDesktopModeSupported(@NonNull Context context) {
+ return context.getResources().getBoolean(R.bool.config_isDesktopModeSupported);
+ }
+
+ /**
+ * Return {@code true} if desktop mode can be entered on the current device.
+ */
+ 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 c2c9442..95237c3 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 @@
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 e73a850..4c69cc3 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 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 @@
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,39 +120,6 @@
}
}
- @Override
- public Context getContext() {
- return mContext;
- }
-
- @Override
- public ShellExecutor getRemoteCallExecutor() {
- return mMainExecutor;
- }
-
- private void onInit() {
- // Ensure that we have the display info in case we get calls to update the bounds before the
- // listener calls back
- mPipDisplayLayoutState.setDisplayId(mContext.getDisplayId());
- DisplayLayout layout = new DisplayLayout(mContext, mContext.getDisplay());
- mPipDisplayLayoutState.setDisplayLayout(layout);
-
- mShellController.addConfigurationChangeListener(this);
- mDisplayController.addDisplayWindowListener(this);
- mDisplayInsetsController.addInsetsChangedListener(mPipDisplayLayoutState.getDisplayId(),
- new DisplayInsetsController.OnInsetsChangedListener() {
- @Override
- public void insetsChanged(InsetsState insetsState) {
- onDisplayChanged(mDisplayController
- .getDisplayLayout(mPipDisplayLayoutState.getDisplayId()));
- }
- });
-
- // 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.
*/
@@ -148,20 +143,70 @@
pipScheduler, mainExecutor);
}
+ private void onInit() {
+ // Ensure that we have the display info in case we get calls to update the bounds before the
+ // listener calls back
+ mPipDisplayLayoutState.setDisplayId(mContext.getDisplayId());
+ DisplayLayout layout = new DisplayLayout(mContext, mContext.getDisplay());
+ mPipDisplayLayoutState.setDisplayLayout(layout);
+
+ mDisplayController.addDisplayWindowListener(this);
+ mDisplayInsetsController.addInsetsChangedListener(mPipDisplayLayoutState.getDisplayId(),
+ new DisplayInsetsController.OnInsetsChangedListener() {
+ @Override
+ public void insetsChanged(InsetsState insetsState) {
+ onDisplayChanged(mDisplayController
+ .getDisplayLayout(mPipDisplayLayoutState.getDisplayId()));
+ }
+ });
+
+ // Allow other outside processes to bind to PiP controller using the key below.
+ mShellController.addExternalInterface(KEY_EXTRA_SHELL_PIP,
+ this::createExternalInterface, this);
+ 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 @@
mPipDisplayLayoutState.setDisplayLayout(layout);
}
+ //
+ // IPip Binder stub helpers
+ //
+
private Rect getSwipePipToHomeBounds(ComponentName componentName, ActivityInfo activityInfo,
PictureInPictureParams pictureInPictureParams,
int launcherRotation, Rect hotseatKeepClearArea) {
@@ -197,18 +246,56 @@
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 @@
@Override
public void invalidate() {
mController = null;
+ mListener.unregister();
}
@Override
@@ -257,7 +345,14 @@
@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 895c793..6665013 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 @@
}
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 dfb0475..d15da4a 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 @@
// 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 @@
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 b5ea1b1..235456c 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 @@
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 @@
// 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 e2be153..1ce87ef 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_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 @@
@CallSuper
protected void removeImmediately() {
mRemoveExecutor.removeCallbacks(mScheduledRunnable);
- mRecordManager.onRecordRemoved(mTaskId);
+ mRecordManager.onRecordRemoved(this, mTaskId);
}
}
@@ -327,6 +328,11 @@
}
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 @@
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 61e11e8..89b0e25 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.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 @@
@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 @@
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 b8a0f67..ccd0b2d 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 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 bf22193..98ff0ee 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 @@
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 @@
&& 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/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 39803e2..c9669a7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -318,11 +318,12 @@
relayoutParams.mCaptionHeightId = getCaptionHeightIdStatic(taskInfo.getWindowingMode());
relayoutParams.mCaptionWidthId = getCaptionWidthId(relayoutParams.mLayoutResId);
- if (captionLayoutId == R.layout.desktop_mode_app_controls_window_decor
- && TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo)) {
- // App is requesting to customize the caption bar. Allow input to fall through to the
- // windows below so that the app can respond to input events on their custom content.
- relayoutParams.mAllowCaptionInputFallthrough = true;
+ if (captionLayoutId == R.layout.desktop_mode_app_controls_window_decor) {
+ // If the app is requesting to customize the caption bar, allow input to fall through
+ // to the windows below so that the app can respond to input events on their custom
+ // content.
+ relayoutParams.mAllowCaptionInputFallthrough =
+ TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo);
// Report occluding elements as bounding rects to the insets system so that apps can
// draw in the empty space in the center:
// First, the "app chip" section of the caption bar (+ some extra margins).
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 92b187f..0136751 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_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.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.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 @@
@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 @@
}
@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 @@
}
@Test
- fun moveToDesktop_screenSizeXLarge_taskIsMovedToDesktop() {
+ fun moveToDesktop_deviceSupported_taskIsMovedToDesktop() {
val task = setUpFullscreenTask()
controller.moveToDesktop(task)
@@ -874,7 +875,8 @@
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 @@
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 83519bb..6940739 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_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.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 @@
@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
-
- onTaskOpening(task)
- verify(mockDesktopModeWindowDecorFactory, never())
- .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun testWindowDecor_screenSizeBelowXLarge_displayRestrictionsOverridden_decorCreated() {
+ fun testWindowDecor_desktopModeUnsupportedOnDevice_decorNotCreated() {
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 default enforce device restrictions system property
+ whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(true)
val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true)
- // Update screen layout to be below minimum size
- task.configuration.screenLayout = SCREENLAYOUT_SIZE_NORMAL
+ // 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_desktopModeUnsupportedOnDevice_deviceRestrictionsOverridden_decorCreated() {
+ val mockitoSession: StaticMockitoSession = mockitoSession()
+ .strictness(Strictness.LENIENT)
+ .spyStatic(DesktopModeStatus::class.java)
+ .startMocking()
+ try {
+ // 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)
setUpMockDecorationsForTasks(task)
onTaskOpening(task)
@@ -403,14 +413,25 @@
@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/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index ba3f6dd..f9b5882 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -173,7 +173,7 @@
}
@Test
- public void updateRelayoutParams_freeformAndTransparent_allowsInputFallthrough() {
+ public void updateRelayoutParams_freeformAndTransparentAppearance_allowsInputFallthrough() {
final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
taskInfo.taskDescription.setSystemBarsAppearance(
@@ -191,7 +191,7 @@
}
@Test
- public void updateRelayoutParams_freeformButOpaque_disallowsInputFallthrough() {
+ public void updateRelayoutParams_freeformButOpaqueAppearance_disallowsInputFallthrough() {
final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
taskInfo.taskDescription.setSystemBarsAppearance(0);
diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig
index 3d7e559..76a0a64 100644
--- a/libs/hwui/aconfig/hwui_flags.aconfig
+++ b/libs/hwui/aconfig/hwui_flags.aconfig
@@ -76,3 +76,10 @@
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 1d03301..abf64d0 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -411,7 +411,8 @@
// 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 2e7a541..254d74a 100644
--- a/location/api/system-current.txt
+++ b/location/api/system-current.txt
@@ -616,8 +616,8 @@
@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 e2c48b9..71644d07 100644
--- a/location/java/android/location/provider/GeocodeProviderBase.java
+++ b/location/java/android/location/provider/GeocodeProviderBase.java
@@ -104,14 +104,14 @@
*/
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 @@
}
}
- 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 @@
}
@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 72aaa35..55c8ed5 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -37,6 +37,7 @@
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 @@
if (ir == null) {
return;
}
+ Trace.beginSection("android.media.ImageReader#postEventFromNative");
final Executor executor;
final OnImageAvailableListener listener;
@@ -948,6 +950,7 @@
}
});
}
+ Trace.endSection();
}
/**
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 9548525..f5dc6ea 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -2345,6 +2345,15 @@
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 @@
* 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 @@
}
// 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 @@
}
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 76664a6..ddcb25b 100644
--- a/media/java/android/media/tv/ad/TvAdManager.java
+++ b/media/java/android/media/tv/ad/TvAdManager.java
@@ -61,7 +61,6 @@
@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 382e65d..371e3d2 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 @@
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 0a2619c..ba084c0 100644
--- a/nfc/java/android/nfc/flags.aconfig
+++ b/nfc/java/android/nfc/flags.aconfig
@@ -2,6 +2,7 @@
flag {
name: "enable_nfc_mainline"
+ is_exported: true
namespace: "nfc"
description: "Flag for NFC mainline changes"
bug: "292140387"
@@ -9,6 +10,7 @@
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 {
name: "enable_nfc_user_restriction"
+ is_exported: true
namespace: "nfc"
description: "Flag for NFC user restriction"
bug: "291187960"
@@ -23,6 +26,7 @@
flag {
name: "nfc_observe_mode"
+ is_exported: true
namespace: "nfc"
description: "Enable NFC Observe Mode"
bug: "294217286"
@@ -30,6 +34,7 @@
flag {
name: "nfc_read_polling_loop"
+ is_exported: true
namespace: "nfc"
description: "Enable NFC Polling Loop Notifications"
bug: "294217286"
@@ -65,6 +70,7 @@
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 {
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 4500a22..5dcfd3b 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/DataBoostWebServiceFlow.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/DataBoostWebServiceFlow.java
@@ -40,7 +40,7 @@
*
* This can be called using the JavaScript below:
* <script type="text/javascript">
- * function getRequestedCapability(duration) {
+ * function getRequestedCapability() {
* DataBoostWebServiceFlow.getRequestedCapability();
* }
* </script>
@@ -57,6 +57,25 @@
*
* 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/drawable/fill_dialog_dynamic_list_item_one_dark.xml b/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_middle.xml
similarity index 60%
rename from packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_one_dark.xml
rename to packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_middle.xml
index 39f49ca..781373d 100644
--- a/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_one_dark.xml
+++ b/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_middle.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ 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.
@@ -15,16 +15,10 @@
~ limitations under the License.
-->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools" tools:ignore="NewApi"
- android:color="@android:color/transparent">
- <item
- android:bottom="1dp"
- android:shape="rectangle"
- android:top="1dp">
- <shape>
- <corners android:radius="28dp" />
- <solid android:color="@android:color/system_surface_container_high_dark" />
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:tools="http://schemas.android.com/tools" tools:ignore="NewApi">
+ <shape android:shape="rectangle">
+ <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
</shape>
- </item>
-</ripple>
\ No newline at end of file
+</inset>
\ No newline at end of file
diff --git a/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_one.xml b/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_one.xml
index f13402c..f28c354 100644
--- a/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_one.xml
+++ b/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_one.xml
@@ -15,16 +15,12 @@
~ limitations under the License.
-->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools" tools:ignore="NewApi"
- android:color="@android:color/transparent">
- <item
- android:bottom="1dp"
- android:shape="rectangle"
- android:top="1dp">
- <shape>
- <corners android:radius="4dp" />
- <solid android:color="@color/dropdown_container" />
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:tools="http://schemas.android.com/tools" tools:ignore="NewApi">
+ <shape android:shape="rectangle">
+ <corners android:topLeftRadius="4dp" android:topRightRadius="4dp"
+ android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp"/>
+ <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
</shape>
- </item>
-</ripple>
\ No newline at end of file
+</inset>
\ No newline at end of file
diff --git a/packages/CredentialManager/res/drawable/more_options_list_item.xml b/packages/CredentialManager/res/drawable/more_options_list_item.xml
index d7b509e..3f9d815 100644
--- a/packages/CredentialManager/res/drawable/more_options_list_item.xml
+++ b/packages/CredentialManager/res/drawable/more_options_list_item.xml
@@ -15,17 +15,16 @@
~ limitations under the License.
-->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools" tools:ignore="NewApi"
- android:color="@android:color/transparent">
- <item
- android:bottom="1dp"
- android:shape="rectangle"
- android:top="1dp">
- <shape>
- <corners android:bottomLeftRadius="4dp"
- android:bottomRightRadius="4dp"/>
- <solid android:color="@color/sign_in_options_container" />
- </shape>
- </item>
-</ripple>
\ No newline at end of file
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:tools="http://schemas.android.com/tools" tools:ignore="NewApi"
+ android:insetLeft="-2dp"
+ android:insetRight="-2dp"
+ android:insetBottom="-2dp">
+ <shape>
+ <corners android:topLeftRadius="0dp" android:topRightRadius="0dp"
+ android:bottomLeftRadius="4dp" android:bottomRightRadius="4dp"/>
+ <solid android:color="?androidprv:attr/materialColorSurfaceContainer"/>
+ <stroke android:color="?androidprv:attr/materialColorOutlineVariant" android:width="1dp"/>
+ </shape>
+</inset>
\ No newline at end of file
diff --git a/packages/CredentialManager/res/layout/credman_dropdown_bottom_sheet.xml b/packages/CredentialManager/res/layout/credman_dropdown_bottom_sheet.xml
index 910ff96..7f09dd5 100644
--- a/packages/CredentialManager/res/layout/credman_dropdown_bottom_sheet.xml
+++ b/packages/CredentialManager/res/layout/credman_dropdown_bottom_sheet.xml
@@ -14,30 +14,52 @@
~ limitations under the License.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@android:id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="@dimen/dropdown_touch_target_min_height"
android:orientation="horizontal"
- android:layout_marginEnd="@dimen/dropdown_layout_horizontal_margin"
android:elevation="3dp">
- <ImageView
- android:id="@android:id/icon1"
+ <LinearLayout
+ android:id="@+id/credential_card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_alignParentStart="true"
- android:contentDescription="@string/more_options_content_description"
- android:background="@null"/>
- <TextView
- android:id="@android:id/text1"
- android:layout_width="wrap_content"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@android:id/icon1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:paddingLeft="@dimen/autofill_view_left_padding"
+ android:src="@drawable/more_horiz_24px"
+ android:tint="?androidprv:attr/materialColorOnSurface"
+ android:layout_alignParentStart="true"
+ android:contentDescription="@string/more_options_content_description"
+ android:background="@null"/>
+
+ <LinearLayout
+ android:id="@+id/text_container"
+ android:layout_width="@dimen/autofill_dropdown_textview_max_width"
android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:layout_toEndOf="@android:id/icon1"
- android:minWidth="@dimen/autofill_dropdown_textview_min_width"
- android:maxWidth="@dimen/autofill_dropdown_textview_max_width"
- style="@style/autofill.TextTitle"/>
+ android:paddingLeft="@dimen/autofill_view_left_padding"
+ android:paddingRight="@dimen/autofill_view_right_padding"
+ android:paddingTop="@dimen/more_options_item_vertical_padding"
+ android:paddingBottom="@dimen/more_options_item_vertical_padding"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@android:id/text1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:layout_toEndOf="@android:id/icon1"
+ style="@style/autofill.TextTitle"/>
+ </LinearLayout>
+
+ </LinearLayout>
</RelativeLayout>
diff --git a/packages/CredentialManager/res/layout/credman_dropdown_presentation_layout.xml b/packages/CredentialManager/res/layout/credman_dropdown_presentation_layout.xml
index 4bf0e99..08948d7 100644
--- a/packages/CredentialManager/res/layout/credman_dropdown_presentation_layout.xml
+++ b/packages/CredentialManager/res/layout/credman_dropdown_presentation_layout.xml
@@ -14,37 +14,60 @@
~ limitations under the License.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@android:id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="@dimen/dropdown_touch_target_min_height"
- android:layout_marginEnd="@dimen/dropdown_layout_horizontal_margin"
android:elevation="3dp">
- <ImageView
- android:id="@android:id/icon1"
+ <LinearLayout
+ android:id="@+id/credential_card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_alignParentStart="true"
- android:background="@null"/>
- <TextView
- android:id="@android:id/text1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:layout_toEndOf="@android:id/icon1"
- android:minWidth="@dimen/autofill_dropdown_textview_min_width"
- android:maxWidth="@dimen/autofill_dropdown_textview_max_width"
- style="@style/autofill.TextTitle"/>
- <TextView
- android:id="@android:id/text2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@android:id/text1"
- android:layout_toEndOf="@android:id/icon1"
- android:minWidth="@dimen/autofill_dropdown_textview_min_width"
- android:maxWidth="@dimen/autofill_dropdown_textview_max_width"
- style="@style/autofill.TextSubtitle"/>
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@android:id/icon1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_alignParentStart="true"
+ android:paddingLeft="@dimen/autofill_view_left_padding"
+ app:tint="?androidprv:attr/materialColorOnSurface"
+ android:background="@null"/>
+
+ <LinearLayout
+ android:id="@+id/text_container"
+ android:layout_width="@dimen/autofill_dropdown_textview_max_width"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/autofill_view_left_padding"
+ android:paddingRight="@dimen/autofill_view_right_padding"
+ android:paddingTop="@dimen/autofill_view_top_padding"
+ android:paddingBottom="@dimen/autofill_view_bottom_padding"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@android:id/text1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_toEndOf="@android:id/icon1"
+ android:textColor="?androidprv:attr/materialColorOnSurface"
+ style="@style/autofill.TextTitle"/>
+
+ <TextView
+ android:id="@android:id/text2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/text1"
+ android:layout_toEndOf="@android:id/icon1"
+ android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ style="@style/autofill.TextSubtitle"/>
+
+ </LinearLayout>
+
+ </LinearLayout>
</RelativeLayout>
diff --git a/packages/CredentialManager/res/values-af/strings.xml b/packages/CredentialManager/res/values-af/strings.xml
index b9ed4a2..5d9295b 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 e1ded6a..2e8021d 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 be55469..a2d328c 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 6b02ea7..3efcea8 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 caef727..627e2c0 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 0248a08..c4111e4 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 cc841d1..f970d16 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 e7027c1..e3758ea3 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 49eb68c..b6f9a88 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 afa4882..6c00ac0 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 c937c09..0d0850f 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 06a81b0..d21afe7 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 207c33c..c868a4b 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 38fa3e9..4fba522 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 509cfe6..ad6a424 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 cd63b41..6aa1b5e 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 cd63b41..6aa1b5e 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 cd63b41..6aa1b5e 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 29fb64d..6bab1ae 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 077ea99..a727f458 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 6de564b..2727612 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 018968c..f0debcc 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 55a79d8..a88b353 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 9f95720..82af70f 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 481fac9..61f2204 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 37df7fb..15715f3 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 8770465..1ca0774 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 efc88c1..7d8df9a 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 661a4a2..b644864 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 eceb1b5..86d52d5 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 3415eea..539feb4 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 af803b4..5f06a7a 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 180c869..ad8aeec 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 332d15e..bc6bdfc 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 5c83336..2b0d83c 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 55fb9f2..ee9dd5d 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 1ffc7db..b60638b 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 fdf0797..c089f4a 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 1c1b186..2200b18 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 0840879..d0faaec 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 84549d1..59e3b5c 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 0c970dd..fd48d18 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 3937ff5..6a01462 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 79a31e8..e71c60f 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 e6bcd06..55c5cd2 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 a62bf28..2c0f8e1 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 b5d5996..6f8f76b 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 fcbd12b..ab32bc9 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 b0d4ca6b..a704ea0 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 5747afd..d3e14dd 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 a6bc11d..a491177 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 55eed78..b427a58 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 f7c5762..1e780ee5 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 bc3fc0e..55d4e87 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 d4ce16b..53b3d70 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 4ca9c39..ad268c9 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 414a4ce..8328d47 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 91e2276..7114c3a 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 105441f..0b03f72 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 f7259d8..b4cf374 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 105441f..0b03f72 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 cfe61a9..8c865c4 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 ba7d34a..92eea32 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 03ada97..ec47018 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 7198625..7426c97 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 3ff85f0..8e08512 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 41f6391..96f1ff0 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 1a5567f..dae62bc 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 8937b01..2326497 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 051122f..6c39509 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 64d4a24..6feb66f 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 066f785..bf3c1e0 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 783d057..4fc8ba0e 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 18283ea..e6bcadd 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 8778797..f9455e7 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 53de1b3..e804777 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 47e33fb..9562fdf 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 6025cae0..4e27d3e7 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 1411036..c774b93 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 dcc2269..11448e9 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 5e893f6..8f69643 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 1e1dca4..b5fa62c 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 72a1e8f..5915a73 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/res/values/colors.xml b/packages/CredentialManager/res/values/colors.xml
index b4d2eeb..9d31b35 100644
--- a/packages/CredentialManager/res/values/colors.xml
+++ b/packages/CredentialManager/res/values/colors.xml
@@ -15,14 +15,12 @@
-->
<!-- Color palette -->
-<resources>
- <!-- These colors are used for Remote Views. -->
- <color name="text_primary">#1A1B20</color>
- <color name="text_secondary">#44474F</color>
- <color name="dropdown_container">#F3F3FA</color>
- <color name="sign_in_options_container">#DADADA</color>
- <color name="sign_in_options_icon_color">#1B1B1B</color>
+<resources
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <!-- These colors are used for Inline Suggestions. -->
- <color name="inline_background">#FFFFFF</color>
+ <!-- These colors are used for Remote Views. -->
+ <color name="onSurface">?androidprv:attr/materialColorOnSurface</color>
+ <color name="onSurfaceVariant">?androidprv:attr/materialColorOnSurfaceVariant</color>
+ <color name="surfaceDim">?androidprv:attr/materialColorSurfaceDim</color>
+ <color name="surfaceContainer">?androidprv:attr/materialColorSurfaceContainer</color>
</resources>
\ No newline at end of file
diff --git a/packages/CredentialManager/res/values/dimens.xml b/packages/CredentialManager/res/values/dimens.xml
index 82dee5c..314437e 100644
--- a/packages/CredentialManager/res/values/dimens.xml
+++ b/packages/CredentialManager/res/values/dimens.xml
@@ -18,16 +18,18 @@
<resources>
<dimen name="autofill_view_top_padding">12dp</dimen>
- <dimen name="autofill_view_right_padding">12dp</dimen>
+ <dimen name="autofill_view_right_padding">16dp</dimen>
<dimen name="autofill_view_bottom_padding">12dp</dimen>
<dimen name="autofill_view_left_padding">16dp</dimen>
- <dimen name="autofill_view_icon_to_text_padding">10dp</dimen>
+ <dimen name="autofill_view_icon_to_text_padding">16dp</dimen>
+ <dimen name="autofill_view_end_items_padding">8dp</dimen>
+ <dimen name="more_options_item_vertical_padding">14dp</dimen>
<dimen name="autofill_icon_size">24dp</dimen>
<dimen name="autofill_dropdown_textview_min_width">112dp</dimen>
<dimen name="autofill_dropdown_textview_max_width">230dp</dimen>
<dimen name="dropdown_layout_horizontal_margin">24dp</dimen>
<integer name="autofill_max_visible_datasets">4</integer>
- <dimen name="dropdown_touch_target_min_height">48dp</dimen>
+ <dimen name="dropdown_touch_target_min_height">49dp</dimen>
<dimen name="horizontal_chip_padding">8dp</dimen>
<dimen name="vertical_chip_padding">6dp</dimen>
</resources>
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
index 271cccb..6ba684d 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
@@ -295,8 +295,9 @@
}
var dropdownPresentation: RemoteViews? = null
if (i < maxDatasetDisplayLimit) {
- dropdownPresentation = RemoteViewsFactory
- .createDropdownPresentation(this, icon, primaryEntry)
+ dropdownPresentation = RemoteViewsFactory.createDropdownPresentation(
+ this, icon, primaryEntry, /*isFirstEntry= */ i == 0,
+ /*isLastEntry= */ (totalEntryCount - i == 1))
}
val dataSetBuilder = Dataset.Builder()
@@ -573,7 +574,7 @@
) {
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)
@@ -603,8 +604,8 @@
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/CredentialManager/src/com/android/credentialmanager/common/ui/RemoteViewsFactory.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/RemoteViewsFactory.kt
index 7966a86..a46e358 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/RemoteViewsFactory.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/RemoteViewsFactory.kt
@@ -31,12 +31,13 @@
private const val setMaxHeightMethodName = "setMaxHeight"
private const val setBackgroundResourceMethodName = "setBackgroundResource"
private const val bulletPoint = "\u2022"
- private const val passwordCharacterLength = 15
fun createDropdownPresentation(
context: Context,
icon: Icon,
- credentialEntryInfo: CredentialEntryInfo
+ credentialEntryInfo: CredentialEntryInfo,
+ isFirstEntry: Boolean,
+ isLastEntry: Boolean,
): RemoteViews {
var layoutId: Int = com.android.credentialmanager.R.layout
.credman_dropdown_presentation_layout
@@ -44,7 +45,6 @@
if (credentialEntryInfo.credentialType == CredentialType.UNKNOWN) {
return remoteViews
}
- setRemoteViewsPaddings(remoteViews, context, /* primaryTextBottomPadding=*/0)
val displayName = credentialEntryInfo.displayName ?: credentialEntryInfo.userName
remoteViews.setTextViewText(android.R.id.text1, displayName)
val secondaryText =
@@ -56,12 +56,6 @@
else (credentialEntryInfo.credentialTypeDisplayName + " " + bulletPoint + " "
+ credentialEntryInfo.providerDisplayName)
remoteViews.setTextViewText(android.R.id.text2, secondaryText)
- val textColorPrimary = ContextCompat.getColor(context,
- com.android.credentialmanager.R.color.text_primary)
- remoteViews.setTextColor(android.R.id.text1, textColorPrimary)
- val textColorSecondary = ContextCompat.getColor(context, com.android
- .credentialmanager.R.color.text_secondary)
- remoteViews.setTextColor(android.R.id.text2, textColorSecondary)
remoteViews.setImageViewIcon(android.R.id.icon1, icon);
remoteViews.setBoolean(
android.R.id.icon1, setAdjustViewBoundsMethodName, true);
@@ -73,9 +67,23 @@
remoteViews.setContentDescription(android.R.id.icon1, credentialEntryInfo
.providerDisplayName);
val drawableId =
- com.android.credentialmanager.R.drawable.fill_dialog_dynamic_list_item_one
+ if (isFirstEntry)
+ com.android.credentialmanager.R.drawable.fill_dialog_dynamic_list_item_one else
+ com.android.credentialmanager.R.drawable.fill_dialog_dynamic_list_item_middle
remoteViews.setInt(
android.R.id.content, setBackgroundResourceMethodName, drawableId);
+ if (isFirstEntry) remoteViews.setViewPadding(
+ com.android.credentialmanager.R.id.credential_card,
+ /* left=*/0,
+ /* top=*/8,
+ /* right=*/0,
+ /* bottom=*/0)
+ if (isLastEntry) remoteViews.setViewPadding(
+ com.android.credentialmanager.R.id.credential_card,
+ /*left=*/0,
+ /* top=*/0,
+ /* right=*/0,
+ /* bottom=*/8)
return remoteViews
}
@@ -83,19 +91,9 @@
var layoutId: Int = com.android.credentialmanager.R.layout
.credman_dropdown_bottom_sheet
val remoteViews = RemoteViews(context.packageName, layoutId)
- setRemoteViewsPaddings(remoteViews, context)
remoteViews.setTextViewText(android.R.id.text1, ContextCompat.getString(context,
com.android.credentialmanager
.R.string.dropdown_presentation_more_sign_in_options_text))
-
- val textColorPrimary = ContextCompat.getColor(context,
- com.android.credentialmanager.R.color.text_primary)
- remoteViews.setTextColor(android.R.id.text1, textColorPrimary)
- val icon = Icon.createWithResource(context, com
- .android.credentialmanager.R.drawable.more_horiz_24px)
- icon.setTint(ContextCompat.getColor(context,
- com.android.credentialmanager.R.color.sign_in_options_icon_color))
- remoteViews.setImageViewIcon(android.R.id.icon1, icon)
remoteViews.setBoolean(
android.R.id.icon1, setAdjustViewBoundsMethodName, true);
remoteViews.setInt(
@@ -109,50 +107,5 @@
android.R.id.content, setBackgroundResourceMethodName, drawableId);
return remoteViews
}
-
- private fun setRemoteViewsPaddings(
- remoteViews: RemoteViews, context: Context) {
- val bottomPadding = context.resources.getDimensionPixelSize(
- com.android.credentialmanager.R.dimen.autofill_view_bottom_padding)
- setRemoteViewsPaddings(remoteViews, context, bottomPadding)
- }
-
- private fun setRemoteViewsPaddings(
- remoteViews: RemoteViews, context: Context, primaryTextBottomPadding: Int) {
- val leftPadding = context.resources.getDimensionPixelSize(
- com.android.credentialmanager.R.dimen.autofill_view_left_padding)
- val iconToTextPadding = context.resources.getDimensionPixelSize(
- com.android.credentialmanager.R.dimen.autofill_view_icon_to_text_padding)
- val rightPadding = context.resources.getDimensionPixelSize(
- com.android.credentialmanager.R.dimen.autofill_view_right_padding)
- val topPadding = context.resources.getDimensionPixelSize(
- com.android.credentialmanager.R.dimen.autofill_view_top_padding)
- val bottomPadding = context.resources.getDimensionPixelSize(
- com.android.credentialmanager.R.dimen.autofill_view_bottom_padding)
- remoteViews.setViewPadding(
- android.R.id.icon1,
- leftPadding,
- /* top=*/0,
- /* right=*/0,
- /* bottom=*/0)
- remoteViews.setViewPadding(
- android.R.id.text1,
- iconToTextPadding,
- /* top=*/topPadding,
- /* right=*/rightPadding,
- primaryTextBottomPadding)
- remoteViews.setViewPadding(
- android.R.id.text2,
- iconToTextPadding,
- /* top=*/0,
- /* right=*/rightPadding,
- /* bottom=*/bottomPadding)
- }
-
- private fun isDarkMode(context: Context): Boolean {
- val currentNightMode = context.resources.configuration.uiMode and
- Configuration.UI_MODE_NIGHT_MASK
- return currentNightMode == Configuration.UI_MODE_NIGHT_YES
- }
}
}
diff --git a/packages/EasterEgg/res/values-night/styles.xml b/packages/EasterEgg/res/values-night/styles.xml
index 4edf692..6ea2eae 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 e576526..4a2cb48f6 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 621a8d7..9d3fb66 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 @@
}
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 ea2fb72..c4c00cb 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.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 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 @@
*/
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 @@
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 @@
}
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 @@
}
}
}
- 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 @@
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 @@
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 @@
}
}
+ private fun ensureEntities(): List<BackupRestoreEntity> =
+ entities ?: createBackupRestoreEntities().also { entities = it }
+
/** Returns if restore is enabled. */
open fun enableRestore(): Boolean = true
@@ -185,7 +183,8 @@
}
final override fun writeNewStateDescription(newState: ParcelFileDescriptor) {
- newState.writeEntityStates(entityStates)
+ entities = null // clear to reduce memory footprint
+ newState.writeAndClearEntityStates()
onRestoreFinished()
}
@@ -223,24 +222,29 @@
}
}
- 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 9866023..3f74ed5 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 @@
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 3216e37..3f68804 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 @@
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 @@
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 7eed745..8b546b4 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 @@
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 3455851..0acf287 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.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 @@
TestTwoTargetSwitchPreference(changeable = true)
}
- composeTestRule.onNodeWithText("TwoTargetSwitchPreference").assertIsDisplayed()
+ composeTestRule.onNodeWithText(TITLE).assertIsDisplayed()
}
@Test
@@ -79,7 +80,7 @@
}
@Test
- fun clickable_canBeClick() {
+ fun clickable_primaryEnabled_canBeClick() {
var clicked = false
composeTestRule.setContent {
TestTwoTargetSwitchPreference(changeable = false) {
@@ -87,26 +88,54 @@
}
}
- 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 bea14c3..5c2d770 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 @@
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 ac85dd4..389b3c1 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 @@
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 @@
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 aba3460..5dfecb0 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 @@
is BlockedByEcm -> model.checked
}
- override val changeable = if (restrictedMode is NoRestricted) model.changeable else ({ false })
+ override val changeable = restrictedMode.restrictEnabled(model.changeable)
- 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 onCheckedChange = restrictedMode.restrictOnClick(model.onCheckedChange)
@Composable
fun RestrictionWrapper(content: @Composable () -> Unit) {
@@ -116,13 +107,12 @@
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 @@
}
}
+ @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 0000000..e100773
--- /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 0000000..bdff89f
--- /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 256a71b..22162bb 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 1150ac1..87b4c0f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -785,30 +785,6 @@
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 @@
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 2d07e5d..6f31fad 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.Implements;
import org.robolectric.shadows.ShadowSettings;
-import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
@@ -547,77 +544,6 @@
}
@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 @@
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 94ea016..7ec3d24 100644
--- a/packages/SettingsProvider/Android.bp
+++ b/packages/SettingsProvider/Android.bp
@@ -67,6 +67,8 @@
"mockito-target-minus-junit4",
"platform-test-annotations",
"truth",
+ "Nene",
+ "Harrier",
],
libs: [
"android.test.base",
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index a490b6f..30d5d4b 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -268,6 +268,7 @@
Settings.Secure.EVEN_DIMMER_MIN_NITS,
Settings.Secure.STYLUS_POINTER_ICON_ENABLED,
Settings.Secure.CAMERA_EXTENSIONS_FALLBACK,
- Settings.Secure.VISUAL_QUERY_ACCESSIBILITY_DETECTION_ENABLED
+ Settings.Secure.VISUAL_QUERY_ACCESSIBILITY_DETECTION_ENABLED,
+ Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 4cdf98cb..893932f 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -423,5 +423,6 @@
VALIDATORS.put(Secure.AUTOFILL_SERVICE, AUTOFILL_SERVICE_VALIDATOR);
VALIDATORS.put(Secure.STYLUS_POINTER_ICON_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.CAMERA_EXTENSIONS_FALLBACK, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.IMMERSIVE_MODE_CONFIRMATIONS, ANY_STRING_VALIDATOR);
}
}
diff --git a/packages/SettingsProvider/test/AndroidTest.xml b/packages/SettingsProvider/test/AndroidTest.xml
index 0bf53cc..dccc2d3 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/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 09d076e..46c89900 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -702,7 +702,6 @@
Settings.Secure.ENABLED_PRINT_SERVICES,
Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE,
Settings.Secure.GLOBAL_ACTIONS_PANEL_DEBUG_ENABLED,
- Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR,
Settings.Secure.INPUT_METHOD_SELECTOR_VISIBILITY,
Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY,
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 0000000..ca1e4c1
--- /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/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 40e39e9..617df74 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -155,6 +155,7 @@
"jsr330",
"lottie",
"LowLightDreamLib",
+ "TraceurCommon",
"motion_tool_lib",
"notification_flags_lib",
"PlatformComposeCore",
@@ -301,6 +302,7 @@
"androidx.compose.material_material-icons-extended",
"androidx.activity_activity-compose",
"androidx.compose.animation_animation-graphics",
+ "TraceurCommon",
],
skip_jarjar_repackage: true,
}
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index d05d40d..da06830 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -610,3 +610,10 @@
description: "Refactors media code to follow the recommended architecture"
bug: "326408371"
}
+
+flag {
+ name: "qs_tile_focus_state"
+ namespace: "systemui"
+ description: "enables new focus outline for qs tiles when focused on with physical keyboard"
+ bug: "312899524"
+}
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 9ee69bc..a3372e3 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.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 @@
fun CommunalContainer(
modifier: Modifier = Modifier,
viewModel: CommunalViewModel,
+ dialogFactory: SystemUIDialogFactory,
) {
val currentScene: SceneKey by viewModel.currentScene.collectAsState(CommunalScenes.Blank)
val sceneTransitionLayoutState =
@@ -104,7 +106,7 @@
userActions =
mapOf(Swipe(SwipeDirection.Right, fromSource = Edge.Left) to CommunalScenes.Blank),
) {
- CommunalScene(viewModel, modifier = modifier)
+ CommunalScene(viewModel, dialogFactory, modifier = modifier)
}
}
}
@@ -113,6 +115,7 @@
@Composable
private fun SceneScope.CommunalScene(
viewModel: BaseCommunalViewModel,
+ dialogFactory: SystemUIDialogFactory,
modifier: Modifier = Modifier,
) {
Box(
@@ -121,5 +124,7 @@
.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 eb6d303..0d6b710 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.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.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.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.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 @@
fun CommunalHub(
modifier: Modifier = Modifier,
viewModel: BaseCommunalViewModel,
+ dialogFactory: SystemUIDialogFactory? = null,
widgetConfigurator: WidgetConfigurator? = null,
onOpenWidgetPicker: (() -> Unit)? = null,
onEditDone: (() -> Unit)? = null,
@@ -165,7 +168,7 @@
.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 @@
)
}
+ 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 @@
}
} else {
CommunalContent(
+ modifier = cardModifier.animateItemPlacement(),
model = list[index],
viewModel = viewModel,
size = size,
selected = false,
- modifier = cardModifier,
)
}
}
@@ -616,7 +644,7 @@
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 @@
) {
val colors = LocalAndroidColorScheme.current
Card(
- modifier = modifier.padding(CardOutlineWidth),
+ modifier = modifier,
colors =
CardDefaults.cardColors(
containerColor = colors.primary,
@@ -716,7 +744,7 @@
}
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 @@
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 @@
@Composable
fun DisabledWidgetPlaceholder(
model: CommunalContentModel.WidgetContent.DisabledWidget,
+ viewModel: BaseCommunalViewModel,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
@@ -843,10 +877,17 @@
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 @@
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 3d88ad5..9e905ac 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.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 @@
@Inject
constructor(
private val viewModel: CommunalViewModel,
+ private val dialogFactory: SystemUIDialogFactory,
) : ComposableScene {
override val key = Scenes.Communal
@@ -51,6 +53,6 @@
@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 0000000..df11206
--- /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 beb8ddef..1adb335 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.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 @@
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 @@
)
val draggingModifier =
if (dragging) {
- Modifier.zIndex(1f).graphicsLayer {
+ Modifier.graphicsLayer {
translationX = dragDropState.draggingItemOffset.x
translationY = dragDropState.draggingItemOffset.y
alpha = itemAlpha
@@ -268,13 +267,14 @@
}
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 bc1e429..379c165 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 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/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
index a02781b..96520b2 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.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 @@
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 @@
destinationScenes(
up = viewModel.upDestinationSceneKey.value,
left = viewModel.leftDestinationSceneKey.value,
+ downFromTopEdge = viewModel.downFromTopEdgeDestinationSceneKey.value,
)
)
@@ -79,12 +88,15 @@
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/qs/footer/ui/compose/FooterActions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
index eb71490..5d9b014 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.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 91b737d..bc48dd1 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 @@
}
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 @@
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 @@
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 3b8b863..6ae1410 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.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 @@
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 82f56ab..975829a 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.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 @@
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 3620cc5..0b9f503 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 @@
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.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,6 +68,7 @@
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
@@ -71,11 +81,7 @@
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 +109,6 @@
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 +119,7 @@
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,15 +140,6 @@
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
@@ -162,8 +152,40 @@
mediaHost: MediaHost,
modifier: Modifier = Modifier,
) {
- val density = LocalDensity.current
- val layoutWidth = remember { mutableStateOf(0) }
+ val isSplitShade by viewModel.isSplitShade.collectAsState()
+ if (isSplitShade) {
+ SplitShade(
+ viewModel = viewModel,
+ createTintedIconManager = createTintedIconManager,
+ createBatteryMeterViewController = createBatteryMeterViewController,
+ statusBarIconController = statusBarIconController,
+ mediaCarouselController = mediaCarouselController,
+ mediaHost = mediaHost,
+ modifier = modifier,
+ )
+ } else {
+ SingleShade(
+ viewModel = viewModel,
+ createTintedIconManager = createTintedIconManager,
+ createBatteryMeterViewController = createBatteryMeterViewController,
+ statusBarIconController = statusBarIconController,
+ mediaCarouselController = mediaCarouselController,
+ mediaHost = mediaHost,
+ modifier = modifier,
+ )
+ }
+}
+
+@Composable
+private fun SceneScope.SingleShade(
+ viewModel: ShadeSceneViewModel,
+ createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
+ createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
+ statusBarIconController: StatusBarIconController,
+ mediaCarouselController: MediaCarouselController,
+ mediaHost: MediaHost,
+ modifier: Modifier = Modifier,
+) {
val maxNotifScrimTop = remember { mutableStateOf(0f) }
val tileSquishiness by
animateSceneFloatAsState(value = 1f, key = QuickSettings.SharedValues.TilesSquishiness)
@@ -203,38 +225,15 @@
(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 +262,133 @@
}
}
}
+
+@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 b9b472f..6cff30c 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.SpringSpec
import kotlin.math.absoluteValue
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
/**
@@ -147,13 +148,16 @@
}
// 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 @@
*/
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 b94e49b..6114499 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 @@
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 @@
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 @@
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 @@
* @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 @@
) {
val swipeTransition =
SwipeTransition(
+ layoutState = layoutState,
+ coroutineScope = draggableHandler.coroutineScope,
fromScene = fromScene,
result = result,
swipes = swipes,
@@ -355,15 +373,9 @@
}
}
- 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 @@
coroutineScope = draggableHandler.coroutineScope,
initialVelocity = velocity,
targetOffset = targetOffset,
- onAnimationCompleted = { snapToScene(targetScene.key) }
+ targetScene = targetScene.key,
)
}
@@ -451,12 +463,14 @@
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 fun SwipeTransition(
+ layoutState: BaseSceneTransitionLayoutState,
+ coroutineScope: CoroutineScope,
fromScene: Scene,
result: UserActionResult,
swipes: Swipes,
@@ -530,6 +546,8 @@
}
return SwipeTransition(
+ layoutState = layoutState,
+ coroutineScope = coroutineScope,
key = result.transitionKey,
_fromScene = fromScene,
_toScene = layoutImpl.scene(result.toScene),
@@ -541,6 +559,8 @@
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 class SwipeTransition(
+ val layoutState: BaseSceneTransitionLayoutState,
+ val coroutineScope: CoroutineScope,
val key: TransitionKey?,
val _fromScene: Scene,
val _toScene: Scene,
@@ -573,7 +595,7 @@
// 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 @@
/** 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 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 @@
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,31 +686,73 @@
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)
+ }
+ }
+
+ 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
+ }
+
+ // 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
}
- }
+
+ val animation =
+ animateOffset(
+ coroutineScope = coroutineScope,
+ initialVelocity = 0f,
+ targetOffset = targetOffset,
+ targetScene = currentScene,
+ )
+ check(offsetAnimation == animation)
+ return animation.job
}
- private suspend fun animateOffset(targetOffset: Float, initialVelocity: Float) {
- if (!isAnimatingOffset) {
- offsetAnimatable.snapTo(dragOffset)
- }
- isAnimatingOffset = true
+ internal class OffsetAnimation(
+ /** The animatable used to animate the offset. */
+ val animatable: Animatable<Float, AnimationVector1D>,
- val animationSpec = transformationSpec
- offsetAnimatable.animateTo(
- targetValue = targetOffset,
- animationSpec = swipeSpec,
- initialVelocity = initialVelocity,
- )
-
- finishOffsetAnimation()
- }
+ /** 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 cdc4778..be066fd 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 @@
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 1670e9c..25b0895 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 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 0fa19bb..86124df 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.StateLink
import kotlin.math.absoluteValue
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.Channel
/**
@@ -188,13 +189,8 @@
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 @@
/** 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 33b57b2..73393a1 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 @@
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 @@
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 eb9b428..1e9a7e2 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.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 @@
}
@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 @@
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 35cb691..224ffe2 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.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 @@
}
@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 3cbcd73..9baabc3 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.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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
@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 @@
// 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 @@
@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 @@
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 @@
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 @@
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 238b21e1..153d2b8 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 @@
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/biometrics/domain/interactor/FingerprintPropertyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorTest.kt
index 97c407c..970ce1f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorTest.kt
@@ -47,6 +47,17 @@
private val displayRepository by lazy { kosmos.displayRepository }
@Test
+ fun propertiesInitialized() =
+ testScope.runTest {
+ val propertiesInitialized by collectLastValue(underTest.propertiesInitialized)
+ assertThat(propertiesInitialized).isFalse()
+
+ repository.supportsUdfps()
+ runCurrent()
+ assertThat(propertiesInitialized).isTrue()
+ }
+
+ @Test
fun sensorLocation_resolution1f() =
testScope.runTest {
val currSensorLocation by collectLastValue(underTest.sensorLocation)
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 0000000..def63ec
--- /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 eafd503..a5707e1 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 @@
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.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.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 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 @@
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 @@
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 @@
}
@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 @@
}
@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 @@
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 c670506..86fdaa5 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.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 @@
@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 9da34da..e34edb4 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.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 @@
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 9ff76be..19950a5 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.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 @@
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 @@
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 63f00c1..6108904 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.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 @@
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 @@
@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 a2c4f4e..42c3354 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 @@
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.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.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 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
+@RunWithLooper
class SceneFrameworkIntegrationTest : SysuiTestCase() {
private val kosmos = testKosmos().apply { fakeSceneContainerFlags.enabled = true }
@@ -167,6 +174,7 @@
interactor = mock(),
),
notifications = kosmos.notificationsPlaceholderViewModel,
+ shadeInteractor = kosmos.shadeInteractor,
)
}
@@ -250,6 +258,9 @@
qsSceneAdapter = qsFlexiglassAdapter,
notifications = kosmos.notificationsPlaceholderViewModel,
mediaDataManager = mediaDataManager,
+ shadeInteractor = kosmos.shadeInteractor,
+ footerActionsController = kosmos.footerActionsController,
+ footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory,
)
kosmos.fakeDeviceEntryRepository.setUnlocked(false)
@@ -337,7 +348,7 @@
@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 @@
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 @@
@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 @@
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/scene/domain/interactor/PanelExpansionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt
similarity index 78%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/PanelExpansionInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt
index 6b5997f..16b68cc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/PanelExpansionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt
@@ -16,24 +16,21 @@
@file:OptIn(ExperimentalCoroutinesApi::class)
-package com.android.systemui.scene.domain.interactor
+package com.android.systemui.shade.domain.interactor
-import android.platform.test.annotations.DisableFlags
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.systemui.Flags.FLAG_SCENE_CONTAINER
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
-import com.android.systemui.shade.data.repository.fakeShadeRepository
-import com.android.systemui.statusbar.notification.stack.ui.viewmodel.panelExpansionInteractor
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -48,7 +45,7 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
-class PanelExpansionInteractorTest : SysuiTestCase() {
+class PanelExpansionInteractorImplTest : SysuiTestCase() {
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
@@ -60,9 +57,8 @@
ObservableTransitionState.Idle(Scenes.Lockscreen)
)
private val fakeSceneDataSource = kosmos.fakeSceneDataSource
- private val fakeShadeRepository = kosmos.fakeShadeRepository
- private lateinit var underTest: PanelExpansionInteractor
+ private lateinit var underTest: PanelExpansionInteractorImpl
@Before
fun setUp() {
@@ -73,7 +69,7 @@
@EnableSceneContainer
fun legacyPanelExpansion_whenIdle_whenLocked() =
testScope.runTest {
- underTest = kosmos.panelExpansionInteractor
+ underTest = kosmos.panelExpansionInteractorImpl
setUnlocked(false)
val panelExpansion by collectLastValue(underTest.legacyPanelExpansion)
@@ -97,7 +93,7 @@
@EnableSceneContainer
fun legacyPanelExpansion_whenIdle_whenUnlocked() =
testScope.runTest {
- underTest = kosmos.panelExpansionInteractor
+ underTest = kosmos.panelExpansionInteractorImpl
setUnlocked(true)
val panelExpansion by collectLastValue(underTest.legacyPanelExpansion)
@@ -116,33 +112,6 @@
changeScene(Scenes.Communal) { assertThat(panelExpansion).isEqualTo(1f) }
assertThat(panelExpansion).isEqualTo(1f)
}
-
- @Test
- @DisableFlags(FLAG_SCENE_CONTAINER)
- fun legacyPanelExpansion_whenInLegacyMode() =
- testScope.runTest {
- underTest = kosmos.panelExpansionInteractor
- val leet = 0.1337f
- fakeShadeRepository.setLegacyShadeExpansion(leet)
- setUnlocked(false)
- val panelExpansion by collectLastValue(underTest.legacyPanelExpansion)
-
- changeScene(Scenes.Lockscreen)
- assertThat(panelExpansion).isEqualTo(leet)
-
- changeScene(Scenes.Bouncer)
- assertThat(panelExpansion).isEqualTo(leet)
-
- changeScene(Scenes.Shade)
- assertThat(panelExpansion).isEqualTo(leet)
-
- changeScene(Scenes.QuickSettings)
- assertThat(panelExpansion).isEqualTo(leet)
-
- changeScene(Scenes.Communal)
- assertThat(panelExpansion).isEqualTo(leet)
- }
-
private fun TestScope.setUnlocked(isUnlocked: Boolean) {
val isDeviceUnlocked by collectLastValue(deviceUnlockedInteractor.isDeviceUnlocked)
deviceEntryRepository.setUnlocked(isUnlocked)
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 b662133..d309c6b 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.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 4cd2c30..4fe45f6 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,11 @@
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.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 +47,20 @@
@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 +87,7 @@
@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 +115,7 @@
@Test
fun qsFullscreen_falseWhenTransitioning() =
- testComponent.runTest {
+ testScope.runTest {
val actual by collectLastValue(underTest.isQsFullscreen)
// WHEN scene transition active
@@ -136,7 +139,7 @@
@Test
fun qsFullscreen_falseWhenIdleNotQS() =
- testComponent.runTest {
+ testScope.runTest {
val actual by collectLastValue(underTest.isQsFullscreen)
// WHEN Idle but not on QuickSettings scene
@@ -154,7 +157,7 @@
@Test
fun qsFullscreen_trueWhenIdleQS() =
- testComponent.runTest {
+ testScope.runTest {
val actual by collectLastValue(underTest.isQsFullscreen)
// WHEN Idle on QuickSettings scene
@@ -172,7 +175,7 @@
@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 +192,7 @@
@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 +210,7 @@
@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 +248,7 @@
@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 +285,7 @@
}
fun isQsBypassingShade_goneToQs() =
- testComponent.runTest {
+ testScope.runTest {
val actual by collectLastValue(underTest.isQsBypassingShade)
// WHEN transitioning from QS directly to Gone
@@ -305,7 +308,7 @@
}
fun isQsBypassingShade_shadeToQs() =
- testComponent.runTest {
+ testScope.runTest {
val actual by collectLastValue(underTest.isQsBypassingShade)
// WHEN transitioning from QS to Shade
@@ -329,7 +332,7 @@
@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 +369,7 @@
@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 +386,7 @@
@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 +424,7 @@
@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 +462,7 @@
@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 +500,7 @@
@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 +538,7 @@
@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 +560,19 @@
// THEN interacting is false
Truth.assertThat(interacting).isFalse()
}
+
+ @Test
+ fun isSplitShade() =
+ testScope.runTest {
+ val isSplitShade by collectLastValue(underTest.isSplitShade)
+
+ shadeRepository.setSplitShade(true)
+ assertThat(isSplitShade).isTrue()
+
+ shadeRepository.setSplitShade(false)
+ assertThat(isSplitShade).isFalse()
+
+ shadeRepository.setSplitShade(true)
+ assertThat(isSplitShade).isTrue()
+ }
}
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 0000000..cbb84da
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.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.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 hydrateSplitShade() =
+ testScope.runTest {
+ overrideResource(R.bool.config_use_split_notification_shade, false)
+ val isSplitShade by collectLastValue(shadeInteractor.isSplitShade)
+
+ underTest.start()
+ assertThat(isSplitShade).isFalse()
+
+ overrideResource(R.bool.config_use_split_notification_shade, true)
+ fakeConfigurationRepository.onAnyConfigurationChange()
+ assertThat(isSplitShade).isTrue()
+
+ overrideResource(R.bool.config_use_split_notification_shade, false)
+ fakeConfigurationRepository.onAnyConfigurationChange()
+ assertThat(isSplitShade).isFalse()
+ }
+}
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 853b00d..2e68d12 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,16 @@
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.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.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,6 +65,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper
class ShadeSceneViewModelTest : SysuiTestCase() {
private val kosmos = testKosmos()
@@ -113,50 +122,56 @@
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 +180,8 @@
runCurrent()
sceneInteractor.changeScene(Scenes.Gone, "reason")
- assertThat(upTransitionSceneKey).isEqualTo(Scenes.Gone)
+ assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene)
+ .isEqualTo(Scenes.Gone)
}
@Test
@@ -239,4 +255,23 @@
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)
+ }
}
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 deb1976..e683f34c 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 @@
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 @@
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 @@
}
@Test
- fun glanceableHubAlpha() =
+ fun glanceableHubAlpha_lockscreenToHub() =
testScope.runTest {
val alpha by collectLastValue(underTest.glanceableHubAlpha)
@@ -278,12 +275,6 @@
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 @@
}
@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 @@
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 @@
)
}
+ 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/drawable/qs_tile_background_flagged.xml b/packages/SystemUI/res/drawable/qs_tile_background_flagged.xml
new file mode 100644
index 0000000..cf7a730
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_tile_background_flagged.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
+ <!-- Since this layer list has just one layer, we can remove it and replace with the inner
+ layer drawable. However this should only be done when the flag
+ com.android.systemui.qs_tile_focus_state has completed all its stages and this drawable
+ fully replaces the previous one to ensure consistency with code sections searching for
+ specific ids in drawable hierarchy -->
+ <item
+ android:id="@id/background">
+ <layer-list>
+ <item
+ android:id="@+id/qs_tile_background_base"
+ android:drawable="@drawable/qs_tile_background_shape" />
+ <item android:id="@+id/qs_tile_background_overlay">
+ <selector>
+ <item
+ android:state_hovered="true"
+ android:drawable="@drawable/qs_tile_background_shape" />
+ </selector>
+ </item>
+ <!-- In the layer below we have negative insets because we need the focus outline
+ to draw outside the bounds, around the main background. We use 5dp because
+ the outline stroke is 3dp and the required padding is 2dp.-->
+ <item
+ android:top="-5dp"
+ android:right="-5dp"
+ android:left="-5dp"
+ android:bottom="-5dp">
+ <selector>
+ <item
+ android:state_focused="true"
+ android:drawable="@drawable/qs_tile_focused_background"/>
+ </selector>
+ </item>
+ </layer-list>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_tile_focused_background.xml b/packages/SystemUI/res/drawable/qs_tile_focused_background.xml
new file mode 100644
index 0000000..fd456df
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_tile_focused_background.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:shape="rectangle">
+ <corners android:radius="30dp"/>
+ <stroke android:width="3dp" android:color="?androidprv:attr/materialColorSecondaryFixed"/>
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 9197149..2e2d286 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 1c9a7941..1427574 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 a4aa842..897820c 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 3fb24b9..ab0b68b 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 07a5bfc..89b4ccf 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 cf050ac..364737d 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 13bb7ea..9a2d744 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 f4268ed..767b34d 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 19cb29b..ebd4073 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 eeb81cc..3457a71 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 6604001..17599b2 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 217d999..75fb325 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 de4fc99..93921fc 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 717e4c9..74fc7c6 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 475076f..f3ae441 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 58fa82b..ddd0c3f 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 c1808a9..0e95c2c 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 5c3c66c..ad32560 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 a08edd2..7abe5ff 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 217d999..75fb325 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 5755353..29ef2f9 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 c1ac5a3..c926e9e 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 18391eb..0bbeb9c 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 0a4d4d0..5345569 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 ad4ff92..2ea1e12 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 2391753..5a53149 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 a2c9f66..edd718f 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 3aae04b..e5f8655 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 7ab38b7..54303b5 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 035f117..a697711 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 4a65cc2..0fcd2b0 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 2576b60..d97c4c9 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 63b2f4a..da1dcd8 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 4a65cc2..0fcd2b0 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 2576b60..d97c4c9 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 4a65cc2..0fcd2b0 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 2576b60..d97c4c9 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 a0d2231..516c3af 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 ede1a74..11e31e1 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 09abc54..6446bdf 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 d487ec1..ec03f8d 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 83b4627..4cc0c67 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 1ccc036..dfbb1ee 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 4f0551d..f16d552 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 5776e091..e41333c 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 accecac..0f6570c 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 6017209..6b5c4cc 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 01a549e..6d6954e 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 7872ef0..78f401f 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 f7a8ec9..545abc9 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 b1c8944..4c4913e 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 7b9708e..d89484d 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 665e81d..5bd34d7 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 af1d09d..a560ff0 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 3764b0f..e694d14 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 a963dec..1cde1ab 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 52fb9ee..5099773 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 580ec10..65b6133 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 892fa62..ea4ccc0 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 3fd0b30..b49d3b9 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 f641463..a6cfeb9 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 217d999..75fb325 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 eadc7da..7a3af4f 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 fad2cd4..3ca3914 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 032b57b..d3b50d7 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 380d9d2..89a94e8 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 5442499..3e34e5f 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 9be5d02..e1d5338 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 077e4de..a707d36 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 1ee6e47..1bd38ba 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 102690a..dc95717 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 28e28ae..f7abea5 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 daca4e3..f88b104 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 bb3eb10..1948685 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 a33b95b..36fc26f 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 ebadf3b..dd78c5e 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 7e3afd9..e77d137 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 07a8a76..2691b69 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 58c3767..6daba135 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 f5b0948..b37e982 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 7a2291d..69adb22 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 a2031b0..0b2d5b3 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 46442ee..f62c2a6 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 de0fcae..3ae6578 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 ffca4bc..40fb618 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 c9b2846..002efb2 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 9de6b66..ef213ca 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 bc47e5a..bb03d0a 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 18ca935..9468502 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 7595897..3c288fc 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 4ea2187..3fc0dcb 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 94343ba..8c4515b 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 82911ee..1a2f8ba 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 d8b2467..a75e9d8 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 64959bf..b6651ad 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 8b0faf7..4dd9e73 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 aa35171..a48d530 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 529d0de..18e7b29 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 4ee598c..625b8b7 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 0db1229..95f835e 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 326c479..b5c0dc7 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 b70a5cc..6902a2f 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 b2afce9..3419e63 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 b72a375..a280916 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 a4f91fa..36984fc 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 d223dc9..ce10c42 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 e968fb5..e126dea 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 2ed0096..71160d0 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 f12bd70..a06c160 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 40159fb..1977706 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 01aa8db..86b2ebe 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 60e35da..7737794 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 9b46c20..afe1e66 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 43bddbf..046db2f 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 ac2badc..8fda667 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 5f0ca17..df870cd 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 a7d2b0a..cfbfa8a 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 5e3a118..c667b99 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 8a4ce33..381c3bd 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 d4fd838..ae2bd05 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 011776c..607a4aa 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 e94b1ec..666963b 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 8a4ce33..381c3bd 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 d4fd838..ae2bd05 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 589b768..857a167 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 75565f9..ed8285d 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 5b16bc5..87150cf 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 3099e00..48ecf26 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 e240c40..e72f1ce 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 48e8cc4..cbbc0e7 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 943adb1..6614c0d 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 fdfcd27db..50f5c25 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 e4b33aa..4a46742 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 3804d63..33ba216 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 3248a96..1fb6251 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 6318700..fa06795 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 a80aee3..3444c80 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 e4cf0b6..55f5a3f 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 49ddff0..2ca3d5d 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 8981ac7..f921f27 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 7fcdc07..b48a0f5 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 08a1f14..227eee8 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 cf2b3ee..b954064 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 741d6de..6043cf2 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 e63ed1f..75f872f 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 6ff2934..370aeb0 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 9d3683e..94243b03 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 d961385..acaf9f0 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 5098f55..99b61e9 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 a12c010..6de62df 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 71de31b..c20c62a 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 c6a8aec..0c086f8 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 c82acb1..3338bce 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 a8e1ab8..fd3fb08 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 16f37bd..bbc7767 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 6d1e707..4957e59 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 5a5ac38..4967115 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 0558c4a..670c56c 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 8c174c0..0b411b5 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 eee10d3..4df2d91 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 c0cdb76..9a75884 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 82ab671..08a1551 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 f263240..2cf6da4 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 6bac275..e29d230 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 35af972..12ca94c 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 5794bf1..85e1796 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 9069964..b6f4a19 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 8c7b652..5c5a67c 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 517f88b..25596cc 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/res/xml/fileprovider.xml b/packages/SystemUI/res/xml/fileprovider.xml
index b67378e..71cc05d 100644
--- a/packages/SystemUI/res/xml/fileprovider.xml
+++ b/packages/SystemUI/res/xml/fileprovider.xml
@@ -19,4 +19,5 @@
<cache-path name="leak" path="leak/"/>
<external-path name="screenrecord" path="."/>
<cache-path name="multi_user" path="multi_user/" />
-</paths>
\ No newline at end of file
+ <root-path name="traces" path="/data/local/traces"/>
+</paths>
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
index 6d4baf4..cd3b8a6 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
@@ -17,6 +17,7 @@
package com.android.systemui.accessibility.floatingmenu;
import static android.view.WindowInsets.Type.ime;
+import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
import static androidx.core.view.WindowInsetsCompat.Type;
@@ -48,6 +49,7 @@
import android.os.Looper;
import android.os.UserHandle;
import android.provider.Settings;
+import android.util.ArraySet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
@@ -64,6 +66,7 @@
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
+import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.internal.accessibility.dialog.AccessibilityTarget;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto;
@@ -162,35 +165,45 @@
final Runnable mDismissMenuAction = new Runnable() {
@Override
public void run() {
- mSecureSettings.putStringForUser(
- Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* value= */ "",
- UserHandle.USER_CURRENT);
+ if (android.view.accessibility.Flags.a11yQsShortcut()) {
+ mAccessibilityManager.enableShortcutsForTargets(
+ /* enable= */ false,
+ ShortcutConstants.UserShortcutType.SOFTWARE,
+ new ArraySet<>(mAccessibilityManager.getAccessibilityShortcutTargets(
+ ACCESSIBILITY_BUTTON)),
+ mSecureSettings.getRealUserHandle(UserHandle.USER_CURRENT)
+ );
+ } else {
+ mSecureSettings.putStringForUser(
+ Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* value= */ "",
+ UserHandle.USER_CURRENT);
- final List<ComponentName> hardwareKeyShortcutComponents =
- mAccessibilityManager.getAccessibilityShortcutTargets(
- ACCESSIBILITY_SHORTCUT_KEY)
- .stream()
- .map(ComponentName::unflattenFromString)
- .toList();
+ final List<ComponentName> hardwareKeyShortcutComponents =
+ mAccessibilityManager.getAccessibilityShortcutTargets(
+ ACCESSIBILITY_SHORTCUT_KEY)
+ .stream()
+ .map(ComponentName::unflattenFromString)
+ .toList();
- // Should disable the corresponding service when the fragment type is
- // INVISIBLE_TOGGLE, which will enable service when the shortcut is on.
- final List<AccessibilityServiceInfo> serviceInfoList =
- mAccessibilityManager.getEnabledAccessibilityServiceList(
- AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
- serviceInfoList.forEach(info -> {
- if (getAccessibilityServiceFragmentType(info) != INVISIBLE_TOGGLE) {
- return;
- }
+ // Should disable the corresponding service when the fragment type is
+ // INVISIBLE_TOGGLE, which will enable service when the shortcut is on.
+ final List<AccessibilityServiceInfo> serviceInfoList =
+ mAccessibilityManager.getEnabledAccessibilityServiceList(
+ AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
+ serviceInfoList.forEach(info -> {
+ if (getAccessibilityServiceFragmentType(info) != INVISIBLE_TOGGLE) {
+ return;
+ }
- final ComponentName serviceComponentName = info.getComponentName();
- if (hardwareKeyShortcutComponents.contains(serviceComponentName)) {
- return;
- }
+ final ComponentName serviceComponentName = info.getComponentName();
+ if (hardwareKeyShortcutComponents.contains(serviceComponentName)) {
+ return;
+ }
- setAccessibilityServiceState(getContext(), serviceComponentName, /* enabled= */
- false);
- });
+ setAccessibilityServiceState(getContext(), serviceComponentName, /* enabled= */
+ false);
+ });
+ }
mFloatingMenu.hide();
}
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 b5a93b6..9f13e6d 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 @@
// 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 @@
// 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/biometrics/data/repository/FingerprintPropertyRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt
index 0c0ed77..40d38dd 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt
@@ -51,6 +51,8 @@
* There is never more than one instance of the FingerprintProperty at any given time.
*/
interface FingerprintPropertyRepository {
+ /** Whether the fingerprint properties have been initialized yet. */
+ val propertiesInitialized: StateFlow<Boolean>
/** The id of fingerprint sensor. */
val sensorId: Flow<Int>
@@ -59,7 +61,7 @@
val strength: Flow<SensorStrength>
/** The types of fingerprint sensor (rear, ultrasonic, optical, etc.). */
- val sensorType: Flow<FingerprintSensorType>
+ val sensorType: StateFlow<FingerprintSensorType>
/** The sensor location relative to each physical display. */
val sensorLocations: Flow<Map<String, SensorLocationInternal>>
@@ -105,15 +107,30 @@
.stateIn(
applicationScope,
started = SharingStarted.Eagerly,
- initialValue = DEFAULT_PROPS,
+ initialValue = UNINITIALIZED_PROPS,
+ )
+
+ override val propertiesInitialized: StateFlow<Boolean> =
+ props
+ .map { it != UNINITIALIZED_PROPS }
+ .stateIn(
+ applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = props.value != UNINITIALIZED_PROPS,
)
override val sensorId: Flow<Int> = props.map { it.sensorId }
override val strength: Flow<SensorStrength> = props.map { it.sensorStrength.toSensorStrength() }
- override val sensorType: Flow<FingerprintSensorType> =
- props.map { it.sensorType.toSensorType() }
+ override val sensorType: StateFlow<FingerprintSensorType> =
+ props
+ .map { it.sensorType.toSensorType() }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = props.value.sensorType.toSensorType(),
+ )
override val sensorLocations: Flow<Map<String, SensorLocationInternal>> =
props.map {
@@ -124,6 +141,17 @@
companion object {
private const val TAG = "FingerprintPropertyRepositoryImpl"
+ private val UNINITIALIZED_PROPS =
+ FingerprintSensorPropertiesInternal(
+ -2 /* sensorId */,
+ SensorProperties.STRENGTH_CONVENIENCE,
+ 0 /* maxEnrollmentsPerUser */,
+ listOf<ComponentInfoInternal>(),
+ FingerprintSensorProperties.TYPE_UNKNOWN,
+ false /* halControlsIllumination */,
+ true /* resetLockoutRequiresHardwareAuthToken */,
+ listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT)
+ )
private val DEFAULT_PROPS =
FingerprintSensorPropertiesInternal(
-1 /* sensorId */,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
index ff9cdbd..5ae2ff0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
@@ -24,22 +24,35 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
@SysUISingleton
class FingerprintPropertyInteractor
@Inject
constructor(
+ @Application private val applicationScope: CoroutineScope,
@Application private val context: Context,
repository: FingerprintPropertyRepository,
configurationInteractor: ConfigurationInteractor,
displayStateInteractor: DisplayStateInteractor,
) {
- val isUdfps: Flow<Boolean> = repository.sensorType.map { it.isUdfps() }
+ val propertiesInitialized: StateFlow<Boolean> = repository.propertiesInitialized
+ val isUdfps: StateFlow<Boolean> =
+ repository.sensorType
+ .map { it.isUdfps() }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = repository.sensorType.value.isUdfps(),
+ )
/**
* Devices with multiple physical displays use unique display ids to determine which sensor is
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 0000000..9e7fb4e
--- /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 8142957..940b48c 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 @@
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.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.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 @@
@Inject
constructor(
@Application applicationScope: CoroutineScope,
+ broadcastDispatcher: BroadcastDispatcher,
private val communalRepository: CommunalRepository,
private val widgetRepository: CommunalWidgetRepository,
private val communalPrefsRepository: CommunalPrefsRepository,
@@ -88,6 +96,8 @@
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 @@
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 @@
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 @@
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 @@
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 12576d4..5fabd3c 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 @@
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 35372cd..85f3c20 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 @@
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 35b27aa..6e69ed7 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 @@
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 @@
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 ce24259..9fa3e5f 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 @@
@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 a3d6ad4..21ee5bd 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.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 @@
@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/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt
index 72b9da6..80b52ed 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt
@@ -16,17 +16,17 @@
package com.android.systemui.deviceentry.domain.interactor
-import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository
+import com.android.systemui.biometrics.domain.interactor.FingerprintPropertyInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.map
/** Encapsulates business logic for device entry under-display fingerprint state changes. */
@ExperimentalCoroutinesApi
@@ -34,14 +34,13 @@
class DeviceEntryUdfpsInteractor
@Inject
constructor(
+ fingerprintPropertyInteractor: FingerprintPropertyInteractor,
// TODO (b/309655554): create & use interactors for these repositories
- fingerprintPropertyRepository: FingerprintPropertyRepository,
fingerprintAuthRepository: DeviceEntryFingerprintAuthRepository,
biometricSettingsRepository: BiometricSettingsRepository,
) {
/** Whether the device supports an under display fingerprint sensor. */
- val isUdfpsSupported: Flow<Boolean> =
- fingerprintPropertyRepository.sensorType.map { it.isUdfps() }
+ val isUdfpsSupported: StateFlow<Boolean> = fingerprintPropertyInteractor.isUdfps
/** Whether the under-display fingerprint sensor is enrolled and enabled for device entry. */
val isUdfpsEnrolledAndEnabled: Flow<Boolean> =
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
index b97bace..f860893 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_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 @@
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 @@
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 @@
}
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 @@
}
launch {
- dreamOverlayViewModel.dreamOverlayAlpha.collect { alpha ->
+ dreamViewModel.dreamOverlayAlpha.collect { alpha ->
ComplicationLayoutParams.iteratePositions(
{ position: Int ->
setElementsAlphaAtPosition(
@@ -120,7 +120,7 @@
}
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 bd99f4b..0000000
--- 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 0000000..0cb57fb
--- /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/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index a37397d..43a8b40 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.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 @@
if (isDream) {
initAlphaForAnimationTargets(wallpapers);
- getRemoteSurfaceAlphaApplier().accept(0.0f);
- mDreamingToLockscreenTransitionViewModel.get()
- .startTransition();
+ mDreamViewModel.get().startTransitionFromDream();
mUnoccludeFromDreamFinishedCallback = finishedCallback;
return;
}
@@ -1359,8 +1357,7 @@
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 @@
SystemSettings systemSettings,
SystemClock systemClock,
@Main CoroutineDispatcher mainDispatcher,
- Lazy<DreamingToLockscreenTransitionViewModel> dreamingToLockscreenTransitionViewModel,
+ Lazy<DreamViewModel> dreamViewModel,
SystemPropertiesHelper systemPropertiesHelper,
Lazy<WindowManagerLockscreenVisibilityManager> wmLockscreenVisibilityManager,
SelectedUserInteractor selectedUserInteractor,
@@ -1480,7 +1477,7 @@
mUiEventLogger = uiEventLogger;
mSessionTracker = sessionTracker;
- mDreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel;
+ mDreamViewModel = dreamViewModel;
mWmLockscreenVisibilityManager = wmLockscreenVisibilityManager;
mMainDispatcher = mainDispatcher;
@@ -1611,9 +1608,8 @@
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 5306645..a243b8e 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.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.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 @@
SystemSettings systemSettings,
SystemClock systemClock,
@Main CoroutineDispatcher mainDispatcher,
- Lazy<DreamingToLockscreenTransitionViewModel> dreamingToLockscreenTransitionViewModel,
+ Lazy<DreamViewModel> dreamViewModel,
SystemPropertiesHelper systemPropertiesHelper,
Lazy<WindowManagerLockscreenVisibilityManager> wmLockscreenVisibilityManager,
SelectedUserInteractor selectedUserInteractor,
@@ -207,7 +207,7 @@
systemSettings,
systemClock,
mainDispatcher,
- dreamingToLockscreenTransitionViewModel,
+ dreamViewModel,
systemPropertiesHelper,
wmLockscreenVisibilityManager,
selectedUserInteractor,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepository.kt
index 0659c7c..a49b3ae 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepository.kt
@@ -19,7 +19,6 @@
import android.os.Handler
import android.util.Log
-import com.android.systemui.common.ui.data.repository.ConfigurationRepository
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.shared.model.KeyguardBlueprint
@@ -30,7 +29,6 @@
import java.io.PrintWriter
import java.util.TreeMap
import javax.inject.Inject
-import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -49,7 +47,6 @@
class KeyguardBlueprintRepository
@Inject
constructor(
- configurationRepository: ConfigurationRepository,
blueprints: Set<@JvmSuppressWildcards KeyguardBlueprint>,
@Main val handler: Handler,
val assert: ThreadAssert,
@@ -60,7 +57,6 @@
TreeMap<String, KeyguardBlueprint>().apply { putAll(blueprints.associateBy { it.id }) }
val blueprint: MutableStateFlow<KeyguardBlueprint> = MutableStateFlow(blueprintIdMap[DEFAULT]!!)
val refreshTransition = MutableSharedFlow<Config>(extraBufferCapacity = 1)
- val configurationChange: Flow<Unit> = configurationRepository.onAnyConfigurationChange
private var targetTransitionConfig: Config? = null
/**
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 3137138..9a6088d 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.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 @@
}
}
+ 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 @@
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 7443010..197221a 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.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.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 @@
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 @@
)
}
} 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/domain/interactor/KeyguardBlueprintInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
index bc3f0cc..c877192 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
@@ -20,6 +20,8 @@
package com.android.systemui.keyguard.domain.interactor
import android.content.Context
+import com.android.systemui.biometrics.domain.interactor.FingerprintPropertyInteractor
+import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.KeyguardBlueprintRepository
@@ -34,7 +36,9 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
@@ -47,6 +51,8 @@
private val context: Context,
private val splitShadeStateController: SplitShadeStateController,
private val clockInteractor: KeyguardClockInteractor,
+ configurationInteractor: ConfigurationInteractor,
+ fingerprintPropertyInteractor: FingerprintPropertyInteractor,
) {
/** The current blueprint for the lockscreen. */
@@ -58,11 +64,14 @@
*/
val refreshTransition = keyguardBlueprintRepository.refreshTransition
+ private val configOrPropertyChange =
+ merge(
+ configurationInteractor.onAnyConfigurationChange,
+ fingerprintPropertyInteractor.propertiesInitialized.filter { it }.map {}, // map to Unit
+ )
init {
applicationScope.launch {
- keyguardBlueprintRepository.configurationChange
- .onStart { emit(Unit) }
- .collect { updateBlueprint() }
+ configOrPropertyChange.onStart { emit(Unit) }.collect { updateBlueprint() }
}
applicationScope.launch { clockInteractor.currentClock.collect { updateBlueprint() } }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
index 3fc9b42..1085f94 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
@@ -26,7 +26,6 @@
import androidx.annotation.VisibleForTesting
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
-import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.LockIconView
import com.android.keyguard.LockIconViewController
import com.android.systemui.Flags.keyguardBottomAreaRefactor
@@ -56,7 +55,6 @@
@Inject
constructor(
@Application private val applicationScope: CoroutineScope,
- private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
private val authController: AuthController,
private val windowManager: WindowManager,
private val context: Context,
@@ -111,7 +109,12 @@
}
override fun applyConstraints(constraintSet: ConstraintSet) {
- val isUdfpsSupported = keyguardUpdateMonitor.isUdfpsSupported
+ val isUdfpsSupported =
+ if (DeviceEntryUdfpsRefactor.isEnabled) {
+ deviceEntryIconViewModel.get().isUdfpsSupported.value
+ } else {
+ authController.isUdfpsSupported
+ }
val scaleFactor: Float = authController.scaleFactor
val mBottomPaddingPx =
context.resources.getDimensionPixelSize(R.dimen.lock_icon_margin_bottom)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
index 662a77e..4c0a949 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
@@ -20,6 +20,8 @@
import android.content.Context
import com.android.settingslib.Utils
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.KeyguardState
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -30,12 +32,14 @@
import kotlinx.coroutines.flow.onStart
/** Models the UI state for the device entry icon background view. */
+@Suppress("WHEN_ENUM_CAN_BE_NULL_IN_JAVA")
@ExperimentalCoroutinesApi
class DeviceEntryBackgroundViewModel
@Inject
constructor(
val context: Context,
val deviceEntryIconViewModel: DeviceEntryIconViewModel,
+ keyguardTransitionInteractor: KeyguardTransitionInteractor,
configurationInteractor: ConfigurationInteractor,
lockscreenToAodTransitionViewModel: LockscreenToAodTransitionViewModel,
aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
@@ -94,6 +98,23 @@
alternateBouncerToDozingTransitionViewModel.deviceEntryBackgroundViewAlpha,
)
.merge()
+ .onStart {
+ when (
+ keyguardTransitionInteractor.currentKeyguardState.replayCache.last()
+ ) {
+ KeyguardState.GLANCEABLE_HUB,
+ KeyguardState.DREAMING_LOCKSCREEN_HOSTED,
+ KeyguardState.GONE,
+ KeyguardState.OCCLUDED,
+ KeyguardState.OFF,
+ KeyguardState.DOZING,
+ KeyguardState.DREAMING,
+ KeyguardState.PRIMARY_BOUNCER,
+ KeyguardState.AOD -> emit(0f)
+ KeyguardState.ALTERNATE_BOUNCER,
+ KeyguardState.LOCKSCREEN -> emit(1f)
+ }
+ }
} else {
flowOf(0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
index bd19c80..1a01897 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
@@ -36,6 +36,7 @@
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
@@ -62,6 +63,7 @@
private val deviceEntryInteractor: DeviceEntryInteractor,
private val deviceEntrySourceInteractor: DeviceEntrySourceInteractor,
) {
+ val isUdfpsSupported: StateFlow<Boolean> = deviceEntryUdfpsInteractor.isUdfpsSupported
private val intEvaluator = IntEvaluator()
private val floatEvaluator = FloatEvaluator()
private val showingAlternateBouncer: Flow<Boolean> =
@@ -137,7 +139,7 @@
) { alpha, alphaMultiplier ->
alpha * alphaMultiplier
}
- val useBackgroundProtection: Flow<Boolean> = deviceEntryUdfpsInteractor.isUdfpsSupported
+ val useBackgroundProtection: StateFlow<Boolean> = isUdfpsSupported
val burnInOffsets: Flow<BurnInOffsets> =
deviceEntryUdfpsInteractor.isUdfpsEnrolledAndEnabled.flatMapLatest { udfpsEnrolled ->
if (udfpsEnrolled) {
@@ -211,7 +213,7 @@
val isLongPressEnabled: Flow<Boolean> =
combine(
iconType,
- deviceEntryUdfpsInteractor.isUdfpsSupported,
+ isUdfpsSupported,
) { deviceEntryStatus, isUdfps ->
when (deviceEntryStatus) {
DeviceEntryIconView.IconType.LOCK -> isUdfps
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 c64f277..789e4fb 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 @@
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 @@
constructor(
animationFlow: KeyguardTransitionAnimationFlow,
configurationInteractor: ConfigurationInteractor,
+ private val fromDreamingTransitionInteractor: FromDreamingTransitionInteractor,
) {
+ fun startTransition() = fromDreamingTransitionInteractor.startToGlanceableHubTransition()
private val transitionAnimation =
animationFlow.setup(
@@ -58,6 +61,9 @@
)
}
+ // 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 d3277cd..f191aa7 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.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 @@
class DreamingToLockscreenTransitionViewModel
@Inject
constructor(
- keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val fromDreamingTransitionInteractor: FromDreamingTransitionInteractor,
animationFlow: KeyguardTransitionAnimationFlow,
) : DeviceEntryIconTransition {
@@ -53,12 +49,6 @@
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/LockscreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
index b60e999..d89523d 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,7 @@
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.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -38,6 +39,7 @@
@Application applicationScope: CoroutineScope,
deviceEntryInteractor: DeviceEntryInteractor,
communalInteractor: CommunalInteractor,
+ shadeInteractor: ShadeInteractor,
val longPress: KeyguardLongPressViewModel,
val notifications: NotificationsPlaceholderViewModel,
) {
@@ -64,4 +66,14 @@
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.isSplitShade
+ .map { isSplitShade -> Scenes.QuickSettings.takeUnless { isSplitShade } }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = null,
+ )
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index e5af8e6..58858df 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -46,7 +46,6 @@
import com.android.systemui.FontSizeUtils;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
-import com.android.systemui.res.R;
import com.android.systemui.qs.QSEditEvent;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.TileLayout;
@@ -57,6 +56,7 @@
import com.android.systemui.qs.dagger.QSThemedContext;
import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.tileimpl.QSTileViewImpl;
+import com.android.systemui.res.R;
import java.util.ArrayList;
import java.util.List;
@@ -319,6 +319,9 @@
}
FrameLayout frame = (FrameLayout) inflater.inflate(R.layout.qs_customize_tile_frame, parent,
false);
+ if (com.android.systemui.Flags.qsTileFocusState()) {
+ frame.setClipChildren(false);
+ }
View view = new CustomizeTileView(context);
frame.addView(view);
return new Holder(frame);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index 9fefcbd..6cc682a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -47,6 +47,7 @@
import androidx.annotation.VisibleForTesting
import com.android.app.tracing.traceSection
import com.android.settingslib.Utils
+import com.android.systemui.Flags
import com.android.systemui.FontSizeUtils
import com.android.systemui.animation.LaunchableView
import com.android.systemui.animation.LaunchableViewDelegate
@@ -134,7 +135,7 @@
*/
protected var showRippleEffect = true
- private lateinit var ripple: RippleDrawable
+ private lateinit var qsTileBackground: LayerDrawable
private lateinit var backgroundDrawable: LayerDrawable
private lateinit var backgroundBaseDrawable: Drawable
private lateinit var backgroundOverlayDrawable: Drawable
@@ -283,15 +284,20 @@
addView(sideView)
}
- fun createTileBackground(): Drawable {
- ripple = mContext.getDrawable(R.drawable.qs_tile_background) as RippleDrawable
- backgroundDrawable = ripple.findDrawableByLayerId(R.id.background) as LayerDrawable
+ private fun createTileBackground(): Drawable {
+ qsTileBackground = if (Flags.qsTileFocusState()) {
+ mContext.getDrawable(R.drawable.qs_tile_background_flagged) as LayerDrawable
+ } else {
+ mContext.getDrawable(R.drawable.qs_tile_background) as RippleDrawable
+ }
+ backgroundDrawable =
+ qsTileBackground.findDrawableByLayerId(R.id.background) as LayerDrawable
backgroundBaseDrawable =
backgroundDrawable.findDrawableByLayerId(R.id.qs_tile_background_base)
backgroundOverlayDrawable =
backgroundDrawable.findDrawableByLayerId(R.id.qs_tile_background_overlay)
backgroundOverlayDrawable.mutate().setTintMode(PorterDuff.Mode.SRC)
- return ripple
+ return qsTileBackground
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
@@ -366,14 +372,16 @@
override fun setClickable(clickable: Boolean) {
super.setClickable(clickable)
- background = if (clickable && showRippleEffect) {
- ripple.also {
- // In case that the colorBackgroundDrawable was used as the background, make sure
- // it has the correct callback instead of null
- backgroundDrawable.callback = it
+ if (!Flags.qsTileFocusState()){
+ background = if (clickable && showRippleEffect) {
+ qsTileBackground.also {
+ // In case that the colorBackgroundDrawable was used as the background, make sure
+ // it has the correct callback instead of null
+ backgroundDrawable.callback = it
+ }
+ } else {
+ backgroundDrawable
}
- } else {
- backgroundDrawable
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt
index 20f3c4d..bd66843 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt
@@ -103,14 +103,27 @@
public override fun handleClick(view: View?) {
if (isRecording) {
isRecording = false
- stopScreenRecord()
+ stopIssueRecordingService()
} else {
mUiHandler.post { showPrompt(view) }
}
refreshState()
}
- private fun stopScreenRecord() =
+ private fun startIssueRecordingService(screenRecord: Boolean, winscopeTracing: Boolean) =
+ PendingIntent.getForegroundService(
+ userContextProvider.userContext,
+ RecordingService.REQUEST_CODE,
+ IssueRecordingService.getStartIntent(
+ userContextProvider.userContext,
+ screenRecord,
+ winscopeTracing
+ ),
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
+ )
+ .send(BroadcastOptions.makeBasic().apply { isInteractive = true }.toBundle())
+
+ private fun stopIssueRecordingService() =
PendingIntent.getService(
userContextProvider.userContext,
RecordingService.REQUEST_CODE,
@@ -124,6 +137,7 @@
delegateFactory
.create {
isRecording = true
+ startIssueRecordingService(it.screenRecord, it.winscopeTracing)
refreshState()
}
.createDialog()
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingConfig.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingConfig.kt
new file mode 100644
index 0000000..bb3b654
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingConfig.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recordissue
+
+data class IssueRecordingConfig(val screenRecord: Boolean, val winscopeTracing: Boolean)
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt
index f487258..0d9b702 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt
@@ -20,7 +20,11 @@
import android.content.Context
import android.content.Intent
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
@@ -30,7 +34,14 @@
import com.android.systemui.screenrecord.RecordingServiceStrings
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
@@ -60,9 +71,118 @@
override fun provideRecordingServiceStrings(): RecordingServiceStrings = IrsStrings(resources)
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ when (intent?.action) {
+ ACTION_START -> {
+ TraceUtils.traceStart(
+ contentResolver,
+ DEFAULT_TRACE_TAGS,
+ DEFAULT_BUFFER_SIZE,
+ DEFAULT_IS_INCLUDING_WINSCOPE,
+ DEFAULT_IS_INCLUDING_APP_TRACE,
+ DEFAULT_IS_LONG_TRACE,
+ DEFAULT_ATTACH_TO_BUGREPORT,
+ DEFAULT_MAX_TRACE_SIZE,
+ DEFAULT_MAX_TRACE_DURATION_IN_MINUTES
+ )
+ if (!intent.getBooleanExtra(EXTRA_SCREEN_RECORD, false)) {
+ // If we don't want to record the screen, the ACTION_SHOW_START_NOTIF action
+ // will circumvent the RecordingService's screen recording start code.
+ return super.onStartCommand(Intent(ACTION_SHOW_START_NOTIF), flags, startId)
+ }
+ }
+ ACTION_STOP,
+ ACTION_STOP_NOTIF -> {
+ TraceUtils.traceStop(contentResolver)
+ }
+ ACTION_SHARE -> {
+ shareRecording(intent)
+
+ // Unlike all other actions, action_share has different behavior for the screen
+ // recording qs tile than it does for the record issue qs tile. Return sticky to
+ // avoid running any of the base class' code for this action.
+ return START_STICKY
+ }
+ else -> {}
+ }
+ return super.onStartCommand(intent, flags, startId)
+ }
+
+ private fun shareRecording(intent: Intent) {
+ val sharableUri: Uri =
+ zipAndPackageRecordings(
+ TraceUtils.traceDump(contentResolver, TRACE_FILE_NAME).get(),
+ intent.getStringExtra(EXTRA_PATH)
+ )
+ ?: return
+ val sendIntent =
+ FileSender.buildSendIntent(this, listOf(sharableUri))
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+
+ if (mNotificationId != NOTIF_BASE_ID) {
+ mNotificationManager.cancelAsUser(
+ null,
+ mNotificationId,
+ UserHandle(mUserContextTracker.userContext.userId)
+ )
+ }
+
+ // TODO: Debug why the notification shade isn't closing upon starting the BetterBug activity
+ mKeyguardDismissUtil.executeWhenUnlocked(
+ {
+ startActivity(sendIntent)
+ false
+ },
+ false,
+ false
+ )
+ }
+
+ 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
+ private const val DEFAULT_IS_INCLUDING_WINSCOPE = true
+ private const val DEFAULT_IS_LONG_TRACE = false
+ private const val DEFAULT_IS_INCLUDING_APP_TRACE = true
+ private const val DEFAULT_ATTACH_TO_BUGREPORT = true
+ private const val DEFAULT_MAX_TRACE_SIZE = 10240
+ private const val DEFAULT_MAX_TRACE_DURATION_IN_MINUTES = 30
+
+ private val TRACE_FILE_NAME = TraceUtils.getOutputFilename(TraceUtils.RecordingType.TRACE)
+ private const val AUTHORITY = "com.android.systemui.fileprovider"
/**
* Get an intent to stop the issue recording service.
@@ -71,7 +191,7 @@
* @return
*/
fun getStopIntent(context: Context): Intent =
- Intent(context, RecordingService::class.java)
+ Intent(context, IssueRecordingService::class.java)
.setAction(ACTION_STOP)
.putExtra(Intent.EXTRA_USER_HANDLE, context.userId)
@@ -80,8 +200,15 @@
*
* @param context Context from the requesting activity
*/
- fun getStartIntent(context: Context): Intent =
- Intent(context, RecordingService::class.java).setAction(ACTION_START)
+ fun getStartIntent(
+ context: Context,
+ screenRecord: Boolean,
+ winscopeTracing: Boolean
+ ): Intent =
+ Intent(context, IssueRecordingService::class.java)
+ .setAction(ACTION_START)
+ .putExtra(EXTRA_SCREEN_RECORD, screenRecord)
+ .putExtra(EXTRA_WINSCOPE_TRACING, winscopeTracing)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
index 1c07d00..ff18a11 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
@@ -17,8 +17,6 @@
package com.android.systemui.recordissue
import android.annotation.SuppressLint
-import android.app.BroadcastOptions
-import android.app.PendingIntent
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
@@ -43,8 +41,6 @@
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDisabledDialogDelegate
import com.android.systemui.qs.tiles.RecordIssueTile
import com.android.systemui.res.R
-import com.android.systemui.screenrecord.RecordingService
-import com.android.systemui.settings.UserContextProvider
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.phone.SystemUIDialog
@@ -52,12 +48,12 @@
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import java.util.concurrent.Executor
+import java.util.function.Consumer
class RecordIssueDialogDelegate
@AssistedInject
constructor(
private val factory: SystemUIDialog.Factory,
- private val userContextProvider: UserContextProvider,
private val userTracker: UserTracker,
private val flags: FeatureFlagsClassic,
@Background private val bgExecutor: Executor,
@@ -66,14 +62,14 @@
private val mediaProjectionMetricsLogger: MediaProjectionMetricsLogger,
private val userFileManager: UserFileManager,
private val screenCaptureDisabledDialogDelegate: ScreenCaptureDisabledDialogDelegate,
- @Assisted private val onStarted: Runnable,
+ @Assisted private val onStarted: Consumer<IssueRecordingConfig>,
) : SystemUIDialog.Delegate {
/** To inject dependencies and allow for easier testing */
@AssistedFactory
interface Factory {
/** Create a dialog object */
- fun create(onStarted: Runnable): RecordIssueDialogDelegate
+ fun create(onStarted: Consumer<IssueRecordingConfig>): RecordIssueDialogDelegate
}
@SuppressLint("UseSwitchCompatOrMaterialCode") private lateinit var screenRecordSwitch: Switch
@@ -87,10 +83,12 @@
setIcon(R.drawable.qs_record_issue_icon_off)
setNegativeButton(R.string.cancel) { _, _ -> dismiss() }
setPositiveButton(R.string.qs_record_issue_start) { _, _ ->
- onStarted.run()
- if (screenRecordSwitch.isChecked) {
- requestScreenCapture()
- }
+ onStarted.accept(
+ IssueRecordingConfig(
+ screenRecordSwitch.isChecked,
+ true /* TODO: Base this on issueType selected */
+ )
+ )
dismiss()
}
}
@@ -177,13 +175,4 @@
show()
}
}
-
- private fun requestScreenCapture() =
- PendingIntent.getForegroundService(
- userContextProvider.userContext,
- RecordingService.REQUEST_CODE,
- IssueRecordingService.getStartIntent(userContextProvider.userContext),
- PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
- )
- .send(BroadcastOptions.makeBasic().apply { isInteractive = true }.toBundle())
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/PanelExpansionInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/PanelExpansionInteractor.kt
deleted file mode 100644
index 3a5ea5c..0000000
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/PanelExpansionInteractor.kt
+++ /dev/null
@@ -1,105 +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.
- */
-
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
-package com.android.systemui.scene.domain.interactor
-
-import com.android.compose.animation.scene.ObservableTransitionState
-import com.android.compose.animation.scene.SceneKey
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.scene.shared.model.Scenes
-import com.android.systemui.shade.data.repository.ShadeRepository
-import javax.inject.Inject
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.map
-
-@SysUISingleton
-class PanelExpansionInteractor
-@Inject
-constructor(
- sceneInteractor: SceneInteractor,
- shadeRepository: ShadeRepository,
-) {
-
- /**
- * The amount by which the "panel" has been expanded (`0` when fully collapsed, `1` when fully
- * expanded).
- *
- * This is a legacy concept from the time when the "panel" included the notification/QS shades
- * as well as the keyguard (lockscreen and bouncer). This value is meant only for
- * backwards-compatibility and should not be consumed by newer code.
- */
- @Deprecated("Use SceneInteractor.currentScene instead.")
- val legacyPanelExpansion: Flow<Float> =
- if (SceneContainerFlag.isEnabled) {
- sceneInteractor.transitionState.flatMapLatest { state ->
- when (state) {
- is ObservableTransitionState.Idle ->
- flowOf(
- if (state.scene != Scenes.Gone) {
- // When resting on a non-Gone scene, the panel is fully expanded.
- 1f
- } else {
- // When resting on the Gone scene, the panel is considered fully
- // collapsed.
- 0f
- }
- )
- is ObservableTransitionState.Transition ->
- when {
- state.fromScene == Scenes.Gone ->
- if (state.toScene.isExpandable()) {
- // Moving from Gone to a scene that can animate-expand has a
- // panel
- // expansion
- // that tracks with the transition.
- state.progress
- } else {
- // Moving from Gone to a scene that doesn't animate-expand
- // immediately makes
- // the panel fully expanded.
- flowOf(1f)
- }
- state.toScene == Scenes.Gone ->
- if (state.fromScene.isExpandable()) {
- // Moving to Gone from a scene that can animate-expand has a
- // panel
- // expansion
- // that tracks with the transition.
- state.progress.map { 1 - it }
- } else {
- // Moving to Gone from a scene that doesn't animate-expand
- // immediately makes
- // the panel fully collapsed.
- flowOf(0f)
- }
- else -> flowOf(1f)
- }
- }
- }
- } else {
- shadeRepository.legacyShadeExpansion
- }
-
- private fun SceneKey.isExpandable(): Boolean {
- return this == Scenes.Shade || this == Scenes.QuickSettings
- }
-}
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 0000000..a490fe2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModel.kt
@@ -0,0 +1,65 @@
+/*
+ * 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 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.isSplitShade
+ .map { isSplitShade -> destinationScenes(isSplitShade = isSplitShade) }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = destinationScenes(isSplitShade = shadeInteractor.isSplitShade.value)
+ )
+
+ private fun destinationScenes(isSplitShade: Boolean): Map<UserAction, UserActionResult> {
+ return buildMap {
+ if (!isSplitShade) {
+ 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/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index b355d2d..ac94f39 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -60,25 +60,27 @@
public static final int REQUEST_CODE = 2;
private static final int USER_ID_NOT_SPECIFIED = -1;
- private static final int NOTIF_BASE_ID = 4273;
+ protected static final int NOTIF_BASE_ID = 4273;
private static final String TAG = "RecordingService";
private static final String CHANNEL_ID = "screen_record";
private static final String GROUP_KEY = "screen_record_saved";
private static final String EXTRA_RESULT_CODE = "extra_resultCode";
- private static final String EXTRA_PATH = "extra_path";
+ protected static final String EXTRA_PATH = "extra_path";
private static final String EXTRA_AUDIO_SOURCE = "extra_useAudio";
private static final String EXTRA_SHOW_TAPS = "extra_showTaps";
private static final String EXTRA_CAPTURE_TARGET = "extra_captureTarget";
protected static final String ACTION_START = "com.android.systemui.screenrecord.START";
+ protected static final String ACTION_SHOW_START_NOTIF =
+ "com.android.systemui.screenrecord.START_NOTIF";
protected static final String ACTION_STOP = "com.android.systemui.screenrecord.STOP";
- private static final String ACTION_STOP_NOTIF =
+ protected static final String ACTION_STOP_NOTIF =
"com.android.systemui.screenrecord.STOP_FROM_NOTIF";
- private static final String ACTION_SHARE = "com.android.systemui.screenrecord.SHARE";
+ protected static final String ACTION_SHARE = "com.android.systemui.screenrecord.SHARE";
private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
private final RecordingController mController;
- private final KeyguardDismissUtil mKeyguardDismissUtil;
+ protected final KeyguardDismissUtil mKeyguardDismissUtil;
private final Handler mMainHandler;
private ScreenRecordingAudioSource mAudioSource;
private boolean mShowTaps;
@@ -86,9 +88,9 @@
private ScreenMediaRecorder mRecorder;
private final Executor mLongExecutor;
private final UiEventLogger mUiEventLogger;
- private final NotificationManager mNotificationManager;
- private final UserContextProvider mUserContextTracker;
- private int mNotificationId = NOTIF_BASE_ID;
+ protected final NotificationManager mNotificationManager;
+ protected final UserContextProvider mUserContextTracker;
+ protected int mNotificationId = NOTIF_BASE_ID;
private RecordingServiceStrings mStrings;
@Inject
@@ -185,7 +187,10 @@
return Service.START_NOT_STICKY;
}
break;
-
+ case ACTION_SHOW_START_NOTIF:
+ createRecordingNotification();
+ mUiEventLogger.log(Events.ScreenRecordEvent.SCREEN_RECORD_START);
+ break;
case ACTION_STOP_NOTIF:
case ACTION_STOP:
// only difference for actions is the log event
@@ -232,6 +237,7 @@
super.onCreate();
}
+ @Nullable
@VisibleForTesting
protected ScreenMediaRecorder getRecorder() {
return mRecorder;
@@ -337,8 +343,9 @@
}
@VisibleForTesting
- protected Notification createSaveNotification(ScreenMediaRecorder.SavedRecording recording) {
- Uri uri = recording.getUri();
+ protected Notification createSaveNotification(
+ @Nullable ScreenMediaRecorder.SavedRecording recording) {
+ Uri uri = recording != null ? recording.getUri() : null;
Intent viewIntent = new Intent(Intent.ACTION_VIEW)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION)
.setDataAndType(uri, "video/mp4");
@@ -349,7 +356,7 @@
PendingIntent.getService(
this,
REQUEST_CODE,
- getShareIntent(this, uri.toString()),
+ getShareIntent(this, uri != null ? uri.toString() : null),
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
.build();
@@ -371,9 +378,10 @@
.addExtras(extras);
// Add thumbnail if available
- if (recording.getThumbnail() != null) {
+ Icon thumbnail = recording != null ? recording.getThumbnail() : null;
+ if (thumbnail != null) {
Notification.BigPictureStyle pictureStyle = new Notification.BigPictureStyle()
- .bigPicture(recording.getThumbnail())
+ .bigPicture(thumbnail)
.showBigPictureWhenCollapsed(true);
builder.setStyle(pictureStyle);
}
@@ -408,27 +416,29 @@
}
Log.d(getTag(), "notifying for user " + userId);
setTapsVisible(mOriginalShowTaps);
- if (getRecorder() != null) {
- try {
+ try {
+ if (getRecorder() != null) {
getRecorder().end();
- saveRecording(userId);
- } catch (RuntimeException exception) {
+ }
+ saveRecording(userId);
+ } catch (RuntimeException exception) {
+ if (getRecorder() != null) {
// RuntimeException could happen if the recording stopped immediately after starting
// let's release the recorder and delete all temporary files in this case
getRecorder().release();
- showErrorToast(R.string.screenrecord_start_error);
- Log.e(getTag(), "stopRecording called, but there was an error when ending"
- + "recording");
- exception.printStackTrace();
- createErrorNotification();
- } catch (Throwable throwable) {
+ }
+ showErrorToast(R.string.screenrecord_start_error);
+ Log.e(getTag(), "stopRecording called, but there was an error when ending"
+ + "recording");
+ exception.printStackTrace();
+ createErrorNotification();
+ } catch (Throwable throwable) {
+ if (getRecorder() != null) {
// Something unexpected happen, SystemUI will crash but let's delete
// the temporary files anyway
getRecorder().release();
- throw new RuntimeException(throwable);
}
- } else {
- Log.e(getTag(), "stopRecording called, but recorder was null");
+ throw new RuntimeException(throwable);
}
updateState(false);
stopForeground(STOP_FOREGROUND_DETACH);
@@ -443,7 +453,8 @@
mLongExecutor.execute(() -> {
try {
Log.d(getTag(), "saving recording");
- Notification notification = createSaveNotification(getRecorder().save());
+ Notification notification = createSaveNotification(
+ getRecorder() != null ? getRecorder().save() : null);
postGroupNotification(currentUser);
mNotificationManager.notifyAsUser(null, mNotificationId, notification,
currentUser);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotViewProxy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotViewProxy.kt
index d8c3850..f01e9be 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.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 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 @@
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 @@
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 @@
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 @@
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 @@
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 1ca9b98..6bab956 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 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.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 @@
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 @@
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 @@
@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 @@
}
/**
- * 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 @@
mScreenshotSoundController.releaseScreenshotSoundAsync();
}
- private void respondToKeyDismissal() {
- dismissScreenshot(SCREENSHOT_DISMISSED_OTHER);
- }
-
/**
* Update resources on configuration change. Reinflate for theme/color changes.
*/
@@ -585,13 +570,6 @@
}
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 @@
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 381404a..d5c7f95 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.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 @@
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 @@
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 @@
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 e464fd0..bc33755 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 @@
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 0991c9a..9cf347b 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 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 @@
// 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 e92630f..92d6ec97 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 @@
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 @@
};
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 @@
@Override
public void onChanged(boolean tracking, int value, boolean stopTracking) {
+ mTrackingTouch = tracking;
if (mExternalChange) return;
if (mSliderAnimator != null) {
@@ -396,6 +398,12 @@
}
}
+ 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 @@
}
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 d3869ba..3169e9c 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.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 @@
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 @@
): 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 a1644b2..cdb520f 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -246,6 +246,7 @@
import javax.inject.Provider;
import kotlinx.coroutines.CoroutineDispatcher;
+import kotlinx.coroutines.flow.Flow;
@SysUISingleton
public final class NotificationPanelViewController implements ShadeSurface, Dumpable {
@@ -1197,7 +1198,8 @@
/* excludeNotifications=*/ true), mMainDispatcher);
collectFlow(mView, mPrimaryBouncerToGoneTransitionViewModel.getNotificationAlpha(),
(Float alpha) -> {
- mNotificationStackScrollLayoutController.setMaxAlphaForExpansion(alpha);
+ mNotificationStackScrollLayoutController.setMaxAlphaForKeyguard(alpha,
+ "mPrimaryBouncerToGoneTransitionViewModel.getNotificationAlpha()");
}, mMainDispatcher);
}
}
@@ -1979,7 +1981,6 @@
mNotificationStackScrollLayoutController.resetScrollPosition();
}
- @Override
public void collapse(boolean animate, boolean delayed, float speedUpFactor) {
boolean waiting = false;
if (animate && !isFullyCollapsed()) {
@@ -1997,7 +1998,6 @@
}
}
- @Override
public void collapse(boolean delayed, float speedUpFactor) {
if (!canBeCollapsed()) {
return;
@@ -2719,7 +2719,8 @@
&& !mQsController.getFullyExpanded()) {
alpha *= mClockPositionResult.clockAlpha;
}
- mNotificationStackScrollLayoutController.setMaxAlphaForExpansion(alpha);
+ mNotificationStackScrollLayoutController.setMaxAlphaForKeyguard(alpha,
+ "NPVC.updateNotificationTranslucency()");
}
}
@@ -2770,7 +2771,9 @@
}
private void onExpandingFinished() {
- mNotificationStackScrollLayoutController.onExpansionStopped();
+ if (!SceneContainerFlag.isEnabled()) {
+ mNotificationStackScrollLayoutController.onExpansionStopped();
+ }
mHeadsUpManager.onExpandingFinished();
mConversationNotificationManager.onNotificationPanelExpandStateChanged(isFullyCollapsed());
mIsExpandingOrCollapsing = false;
@@ -3085,7 +3088,9 @@
// The expandedHeight is always the full panel Height when bypassing
expandedHeight = getMaxPanelHeight();
}
- mNotificationStackScrollLayoutController.setExpandedHeight(expandedHeight);
+ if (!SceneContainerFlag.isEnabled()) {
+ mNotificationStackScrollLayoutController.setExpandedHeight(expandedHeight);
+ }
updateKeyguardBottomAreaAlpha();
updateStatusBarIcons();
}
@@ -4000,11 +4005,15 @@
}
@Override
+ public Flow<Float> getLegacyPanelExpansion() {
+ return mShadeRepository.getLegacyShadeExpansion();
+ }
+
+ @Override
public boolean isFullyExpanded() {
return mExpandedHeight >= getMaxPanelTransitionDistance();
}
- @Override
public boolean isShadeFullyExpanded() {
if (mBarState == SHADE) {
return isFullyExpanded();
@@ -4035,7 +4044,6 @@
return !isFullyCollapsed() && !isTracking() && !isClosing();
}
- @Override
public void instantCollapse() {
abortAnimations();
setExpandedFraction(0f);
@@ -4729,7 +4737,7 @@
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/QuickSettingsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
index 19d98a0..fd68c56 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.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 @@
// 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 @@
/** 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/ShadeEmptyImplModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeEmptyImplModule.kt
index 4054a86..25e27ae 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeEmptyImplModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeEmptyImplModule.kt
@@ -21,6 +21,7 @@
import com.android.systemui.shade.data.repository.PrivacyChipRepositoryImpl
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.shade.data.repository.ShadeRepositoryImpl
+import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractor
import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractorEmptyImpl
import com.android.systemui.shade.domain.interactor.ShadeBackActionInteractor
@@ -66,5 +67,11 @@
@Binds
@SysUISingleton
+ abstract fun bindsPanelExpansionInteractor(
+ sbai: ShadeViewControllerEmptyImpl
+ ): PanelExpansionInteractor
+
+ @Binds
+ @SysUISingleton
abstract fun bindsPrivacyChipRepository(impl: PrivacyChipRepositoryImpl): PrivacyChipRepository
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
index 504dbfd..3e9a32b 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
@@ -25,6 +25,8 @@
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.shade.data.repository.ShadeRepositoryImpl
import com.android.systemui.shade.domain.interactor.BaseShadeInteractor
+import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
+import com.android.systemui.shade.domain.interactor.PanelExpansionInteractorImpl
import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractor
import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractorLegacyImpl
import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractorSceneContainerImpl
@@ -116,6 +118,20 @@
@Provides
@SysUISingleton
+ fun providePanelExpansionInteractor(
+ sceneContainerFlags: SceneContainerFlags,
+ sceneContainerOn: Provider<PanelExpansionInteractorImpl>,
+ sceneContainerOff: Provider<NotificationPanelViewController>
+ ): PanelExpansionInteractor {
+ return if (sceneContainerFlags.isEnabled()) {
+ sceneContainerOn.get()
+ } else {
+ sceneContainerOff.get()
+ }
+ }
+
+ @Provides
+ @SysUISingleton
fun provideQuickSettingsController(
sceneContainerFlags: SceneContainerFlags,
sceneContainerOn: Provider<QuickSettingsControllerSceneImpl>,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt
index 941c6f3..5c276b1 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt
@@ -16,6 +16,7 @@
package com.android.systemui.shade
import android.view.ViewPropertyAnimator
+import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
import com.android.systemui.shade.domain.interactor.ShadeBackActionInteractor
import com.android.systemui.statusbar.GestureRecorder
import com.android.systemui.statusbar.phone.CentralSurfaces
@@ -26,7 +27,11 @@
* this class. If any method in this class is needed outside of CentralSurfacesImpl, it must be
* pulled up into ShadeViewController.
*/
-interface ShadeSurface : ShadeViewController, ShadeBackActionInteractor, ShadeLockscreenInteractor {
+interface ShadeSurface :
+ ShadeViewController,
+ ShadeBackActionInteractor,
+ ShadeLockscreenInteractor,
+ PanelExpansionInteractor {
/** Initialize objects instead of injecting to avoid circular dependencies. */
fun initDependencies(
centralSurfaces: CentralSurfaces,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
index 7a1637e..07236d1 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
@@ -40,25 +40,6 @@
*/
val isPanelExpanded: Boolean
- /** Returns whether the shade is fully expanded in either QS or QQS. */
- val isShadeFullyExpanded: Boolean
-
- /**
- * Animates the collapse of a shade with the given delay and the default duration divided by
- * speedUpFactor.
- */
- fun collapse(delayed: Boolean, speedUpFactor: Float)
-
- /** Collapses the shade. */
- fun collapse(animate: Boolean, delayed: Boolean, speedUpFactor: Float)
-
- /** Collapses the shade instantly without animation. */
- fun instantCollapse()
-
- /** Returns whether the shade can be collapsed. */
- @Deprecated("Do not use outside of the shade package. Not supported by scenes.")
- fun canBeCollapsed(): Boolean
-
/** Returns whether the shade is in the process of collapsing. */
val isCollapsing: Boolean
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt
index 3be3f6b..6e03686 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt
@@ -19,23 +19,24 @@
import android.view.MotionEvent
import android.view.ViewGroup
import android.view.ViewTreeObserver
+import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
import com.android.systemui.shade.domain.interactor.ShadeBackActionInteractor
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController
import java.util.function.Consumer
import javax.inject.Inject
+import kotlinx.coroutines.flow.flowOf
/** Empty implementation of ShadeViewController for variants with no shade. */
class ShadeViewControllerEmptyImpl @Inject constructor() :
- ShadeViewController, ShadeBackActionInteractor, ShadeLockscreenInteractor {
+ ShadeViewController,
+ ShadeBackActionInteractor,
+ ShadeLockscreenInteractor,
+ PanelExpansionInteractor {
override fun expandToNotifications() {}
override val isExpandingOrCollapsing: Boolean = false
override val isExpanded: Boolean = false
override val isPanelExpanded: Boolean = false
- override val isShadeFullyExpanded: Boolean = false
- override fun collapse(delayed: Boolean, speedUpFactor: Float) {}
- override fun collapse(animate: Boolean, delayed: Boolean, speedUpFactor: Float) {}
- override fun instantCollapse() {}
override fun animateCollapseQs(fullyCollapse: Boolean) {}
override fun canBeCollapsed(): Boolean = false
override val isCollapsing: Boolean = false
@@ -86,6 +87,7 @@
override val shadeHeadsUpTracker = ShadeHeadsUpTrackerEmptyImpl()
override val shadeFoldAnimator = ShadeFoldAnimatorEmptyImpl()
+ override val legacyPanelExpansion = flowOf(0f)
}
class ShadeHeadsUpTrackerEmptyImpl : ShadeHeadsUpTracker {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/StartShadeModule.kt b/packages/SystemUI/src/com/android/systemui/shade/StartShadeModule.kt
index 15ec18c..c4de78b 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 @@
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 @@
@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/data/repository/ShadeRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
index e5ff977..e050c0b 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
@@ -100,12 +100,17 @@
@Deprecated("Use ShadeInteractor.isQsBypassingShade instead")
val legacyExpandImmediate: StateFlow<Boolean>
+ /** Whether the current configuration requires the split shade to be shown. */
+ val isSplitShade: StateFlow<Boolean>
+
/** 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 setSplitShade(isSplitShade: Boolean)
+
/** Sets whether a closing animation is happening. */
@Deprecated("Use ShadeAnimationInteractor instead") fun setLegacyIsClosing(isClosing: Boolean)
@@ -214,6 +219,13 @@
@Deprecated("Use ShadeInteractor instead")
override val legacyQsFullscreen: StateFlow<Boolean> = _legacyQsFullscreen.asStateFlow()
+ val _isSplitShade = MutableStateFlow(false)
+ override val isSplitShade: StateFlow<Boolean> = _isSplitShade.asStateFlow()
+
+ override fun setSplitShade(isSplitShade: Boolean) {
+ _isSplitShade.value = isSplitShade
+ }
+
override fun setLegacyQsFullscreen(legacyQsFullscreen: Boolean) {
_legacyQsFullscreen.value = legacyQsFullscreen
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractor.kt
new file mode 100644
index 0000000..01118bd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractor.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.shade.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * Expansion-related methods used throughout SysUI before the addition of the scene container as the
+ * top layer component. This interface exists to allow the scene container to fulfil
+ * NotificationPanelViewController's contracts with the rest of SysUI. Once the scene container is
+ * the only shade implementation in SysUI, the remaining implementation of this should be deleted
+ * after inlining all of its method bodies. No new calls to any of these methods should be added.
+ */
+@SysUISingleton
+@Deprecated("Use ShadeInteractor instead.")
+interface PanelExpansionInteractor {
+ /**
+ * The amount by which the "panel" has been expanded (`0` when fully collapsed, `1` when fully
+ * expanded).
+ *
+ * This is a legacy concept from the time when the "panel" included the notification/QS shades
+ * as well as the keyguard (lockscreen and bouncer). This value is meant only for
+ * backwards-compatibility and should not be consumed by newer code.
+ */
+ @Deprecated("Use SceneInteractor.currentScene instead.") val legacyPanelExpansion: Flow<Float>
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImpl.kt
new file mode 100644
index 0000000..20f73b0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImpl.kt
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.shade.domain.interactor
+
+import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.SceneKey
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
+import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
+
+@SysUISingleton
+class PanelExpansionInteractorImpl
+@Inject
+constructor(
+ sceneInteractor: SceneInteractor,
+) : PanelExpansionInteractor {
+
+ /**
+ * The amount by which the "panel" has been expanded (`0` when fully collapsed, `1` when fully
+ * expanded).
+ *
+ * This is a legacy concept from the time when the "panel" included the notification/QS shades
+ * as well as the keyguard (lockscreen and bouncer). This value is meant only for
+ * backwards-compatibility and should not be consumed by newer code.
+ */
+ @Deprecated("Use SceneInteractor.currentScene instead.")
+ override val legacyPanelExpansion: Flow<Float> =
+ sceneInteractor.transitionState.flatMapLatest { state ->
+ when (state) {
+ is ObservableTransitionState.Idle ->
+ flowOf(
+ if (state.scene != Scenes.Gone) {
+ // When resting on a non-Gone scene, the panel is fully expanded.
+ 1f
+ } else {
+ // When resting on the Gone scene, the panel is considered fully
+ // collapsed.
+ 0f
+ }
+ )
+ is ObservableTransitionState.Transition ->
+ when {
+ state.fromScene == Scenes.Gone ->
+ if (state.toScene.isExpandable()) {
+ // Moving from Gone to a scene that can animate-expand has a
+ // panel
+ // expansion
+ // that tracks with the transition.
+ state.progress
+ } else {
+ // Moving from Gone to a scene that doesn't animate-expand
+ // immediately makes
+ // the panel fully expanded.
+ flowOf(1f)
+ }
+ state.toScene == Scenes.Gone ->
+ if (state.fromScene.isExpandable()) {
+ // Moving to Gone from a scene that can animate-expand has a
+ // panel
+ // expansion
+ // that tracks with the transition.
+ state.progress.map { 1 - it }
+ } else {
+ // Moving to Gone from a scene that doesn't animate-expand
+ // immediately makes
+ // the panel fully collapsed.
+ flowOf(0f)
+ }
+ else -> flowOf(1f)
+ }
+ }
+ }
+
+ private fun SceneKey.isExpandable(): Boolean {
+ return this == Scenes.Shade || this == Scenes.QuickSettings
+ }
+}
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 43ede2a..ad3fbe5 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
@@ -102,6 +102,9 @@
* animating.
*/
val isUserInteractingWithQs: Flow<Boolean>
+
+ /** Whether the current configuration requires the split shade to be shown. */
+ val isSplitShade: StateFlow<Boolean>
}
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 55dd674..57a36b5 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
@@ -42,4 +42,5 @@
override val isUserInteracting: StateFlow<Boolean> = inactiveFlowBoolean
override val isShadeTouchable: Flow<Boolean> = inactiveFlowBoolean
override val isExpandToQsEnabled: Flow<Boolean> = inactiveFlowBoolean
+ override val isSplitShade: StateFlow<Boolean> = inactiveFlowBoolean
}
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 2ac3193..3bccd2b 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
@@ -99,6 +99,8 @@
override val isUserInteractingWithQs: Flow<Boolean> =
userInteractingFlow(repository.legacyQsTracking, repository.qsExpansion)
+ override val isSplitShade: StateFlow<Boolean> = repository.isSplitShade
+
/**
* 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 67cac3d..ad8c029 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,7 @@
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.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -45,6 +46,7 @@
@Application scope: CoroutineScope,
sceneInteractor: SceneInteractor,
sharedNotificationContainerInteractor: SharedNotificationContainerInteractor,
+ shadeRepository: ShadeRepository,
) : BaseShadeInteractor {
override val shadeExpansion: Flow<Float> = sceneBasedExpansion(sceneInteractor, Scenes.Shade)
@@ -106,6 +108,8 @@
override val isUserInteractingWithQs: Flow<Boolean> =
sceneBasedInteracting(sceneInteractor, Scenes.QuickSettings)
+ override val isSplitShade: StateFlow<Boolean> = shadeRepository.isSplitShade
+
/**
* 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 0000000..334908e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt
@@ -0,0 +1,57 @@
+/*
+ * 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.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() {
+ hydrateSplitShade()
+ }
+
+ private fun hydrateSplitShade() {
+ applicationScope.launch {
+ configurationRepository.onAnyConfigurationChange
+ // Force initial collection.
+ .onStart { emit(Unit) }
+ .map { applicationContext.resources }
+ .map { resources -> controller.shouldUseSplitNotificationShade(resources) }
+ .collect { isSplitShade -> shadeRepository.setSplitShade(isSplitShade) }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
index 84afbed..3a5c5e1 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
@@ -22,7 +22,7 @@
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.qs.QS
-import com.android.systemui.scene.domain.interactor.PanelExpansionInteractor
+import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.PanelState
import com.android.systemui.shade.ShadeExpansionChangeEvent
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 c9aa51c..8084a6f 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,31 @@
* 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.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 +56,36 @@
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.isSplitShade,
+ ) { isUnlocked, canSwipeToDismiss, isSplitShade ->
+ destinationScenes(
isUnlocked = isUnlocked,
canSwipeToDismiss = canSwipeToDismiss,
+ isSplitShade = isSplitShade,
)
}
.stateIn(
scope = applicationScope,
started = SharingStarted.WhileSubscribed(),
initialValue =
- upDestinationSceneKey(
+ destinationScenes(
isUnlocked = deviceEntryInteractor.isUnlocked.value,
canSwipeToDismiss = deviceEntryInteractor.canSwipeToEnter.value,
+ isSplitShade = shadeInteractor.isSplitShade.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 +96,43 @@
initialValue = false
)
+ /** Whether the current configuration requires the split shade to be shown. */
+ val isSplitShade: StateFlow<Boolean> = shadeInteractor.isSplitShade
+
/** 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?,
+ isSplitShade: Boolean,
+ ): Map<UserAction, UserActionResult> {
+ val up =
+ when {
+ canSwipeToDismiss == true -> Scenes.Lockscreen
+ isUnlocked -> Scenes.Gone
+ else -> Scenes.Lockscreen
+ }
+
+ val down = if (isSplitShade) null else Scenes.QuickSettings
+
+ 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/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 81f644f..4b16126 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -594,6 +594,7 @@
}
}
val cancelHandler = Runnable {
+ statusBarStateController.setLeaveOpenOnKeyguardHide(false)
draggedDownEntry?.apply {
setUserLocked(false)
notifyHeightChanged(
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 deaf1d1..dfb0f9b 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 @@
/* 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 18460c3..7b8a062 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 @@
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 0b9d19d..e0e5a35 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.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.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 @@
@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 @@
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 @@
dirtyListeners.remove(listener)
if (dirtyListeners.isEmpty()) {
lockscreenUserManager.removeNotificationStateChangedListener(notifStateChangedListener)
+ if (screenshareNotificationHiding()) {
+ sensitiveNotifProtectionController.unregisterSensitiveStateListener(
+ onSensitiveStateChangedListener
+ )
+ }
secureSettings.unregisterContentObserver(settingsObserver)
}
}
@@ -89,6 +102,8 @@
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 @@
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 c5b55c7..6400ff6 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 @@
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 38f21ee..b205071 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 @@
}
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 @@
}
// 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 382de3f..6553193 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 @@
};
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 @@
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 @@
private void updateAlpha() {
if (mView != null) {
- mView.setAlpha(Math.min(mMaxAlphaForExpansion,
+ mView.setAlpha(Math.min(mMaxAlphaForKeyguard,
Math.min(mMaxAlphaForUnhide, mMaxAlphaForGlanceableHub)));
}
}
@@ -1831,9 +1837,10 @@
@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 76495cb..8b1b06e 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 @@
}
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 566c030..ece7a7f 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 @@
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 @@
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 3a9cdd2..2745817 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.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 @@
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 @@
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 @@
)
.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 @@
}
.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 @@
},
)
.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 23a080b..a55de25 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 @@
}
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/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index 48d3157..e2e13a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -301,8 +301,7 @@
if (KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP == key.getKeyCode()) {
mMetricsLogger.action(MetricsEvent.ACTION_SYSTEM_NAVIGATION_KEY_UP);
- mShadeViewController.collapse(
- false /* delayed */, 1.0f /* speedUpFactor */);
+ mShadeController.animateCollapseShade();
} else if (KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN == key.getKeyCode()) {
mMetricsLogger.action(MetricsEvent.ACTION_SYSTEM_NAVIGATION_KEY_DOWN);
if (mShadeViewController.isFullyCollapsed()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index db15144..d32e88b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -2790,6 +2790,9 @@
|| mKeyguardStateController.isKeyguardGoingAway()
|| mKeyguardViewMediator.requestedShowSurfaceBehindKeyguard()
|| mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());
+ boolean dreaming =
+ mKeyguardStateController.isShowing() && mKeyguardUpdateMonitor.isDreaming()
+ && !unlocking;
mScrimController.setExpansionAffectsAlpha(!unlocking);
@@ -2834,13 +2837,16 @@
// this as otherwise it can remain pending and leave keyguard in a weird state.
mUnlockScrimCallback.onCancelled();
} else if (mIsIdleOnCommunal) {
- mScrimController.transitionTo(ScrimState.GLANCEABLE_HUB);
+ if (dreaming) {
+ mScrimController.transitionTo(ScrimState.GLANCEABLE_HUB_OVER_DREAM);
+ } else {
+ mScrimController.transitionTo(ScrimState.GLANCEABLE_HUB);
+ }
} else if (mKeyguardStateController.isShowing()
&& !mKeyguardStateController.isOccluded()
&& !unlocking) {
mScrimController.transitionTo(ScrimState.KEYGUARD);
- } else if (mKeyguardStateController.isShowing() && mKeyguardUpdateMonitor.isDreaming()
- && !unlocking) {
+ } else if (dreaming) {
mScrimController.transitionTo(ScrimState.DREAMING);
} else {
mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
@@ -3043,8 +3049,7 @@
if (userSetup != mUserSetup) {
mUserSetup = userSetup;
if (!mUserSetup && mState == StatusBarState.SHADE) {
- mShadeSurface.collapse(true /* animate */, false /* delayed */,
- 1.0f /* speedUpFactor */);
+ mShadeController.animateCollapseShade();
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 088f894..02293a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -536,6 +536,16 @@
mAnimateChange = state.getAnimateChange();
mAnimationDuration = state.getAnimationDuration();
+ if (mState == ScrimState.GLANCEABLE_HUB_OVER_DREAM) {
+ // When the device is docked while on GLANCEABLE_HUB, the dream starts underneath the
+ // hub and the ScrimState transitions to GLANCEABLE_HUB_OVER_DREAM. To prevent the
+ // scrims from flickering in during this transition, we set the panel expansion
+ // fraction, which is 1 when idle on GLANCEABLE_HUB, to 0. This only occurs when the hub
+ // is open because the hub lives in the same window as the shade, which is not visible
+ // when transitioning from KEYGUARD to DREAMING.
+ mPanelExpansionFraction = 0f;
+ }
+
applyState();
mScrimInFront.setBlendWithMainColor(state.shouldBlendWithMainColor());
@@ -738,6 +748,7 @@
boolean relevantState = (mState == ScrimState.UNLOCKED
|| mState == ScrimState.KEYGUARD
|| mState == ScrimState.DREAMING
+ || mState == ScrimState.GLANCEABLE_HUB_OVER_DREAM
|| mState == ScrimState.SHADE_LOCKED
|| mState == ScrimState.PULSING);
if (!(relevantState && mExpansionAffectsAlpha) || mAnimatingPanelExpansionOnUnlock) {
@@ -844,7 +855,8 @@
return;
}
mBouncerHiddenFraction = bouncerHiddenAmount;
- if (mState == ScrimState.DREAMING || mState == ScrimState.GLANCEABLE_HUB) {
+ if (mState == ScrimState.DREAMING || mState == ScrimState.GLANCEABLE_HUB
+ || mState == ScrimState.GLANCEABLE_HUB_OVER_DREAM) {
// The dreaming and glanceable hub states requires this for the scrim calculation, so we
// should only trigger an update in those states.
applyAndDispatchState();
@@ -926,7 +938,8 @@
return;
}
- if (mState == ScrimState.UNLOCKED || mState == ScrimState.DREAMING) {
+ if (mState == ScrimState.UNLOCKED || mState == ScrimState.DREAMING
+ || mState == ScrimState.GLANCEABLE_HUB_OVER_DREAM) {
final boolean occluding =
mOccludeAnimationPlaying || mState.mLaunchingAffordanceWithPreview;
// Darken scrim as it's pulled down while unlocked. If we're unlocked but playing the
@@ -954,8 +967,9 @@
mInFrontAlpha = 0;
}
- if (mState == ScrimState.DREAMING
+ if ((mState == ScrimState.DREAMING || mState == ScrimState.GLANCEABLE_HUB_OVER_DREAM)
&& mBouncerHiddenFraction != KeyguardBouncerConstants.EXPANSION_HIDDEN) {
+ // Bouncer is opening over dream or glanceable hub over dream.
final float interpolatedFraction =
BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(
mBouncerHiddenFraction);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index f2a649b..d4960d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -299,9 +299,9 @@
},
/**
- * Device is locked or on dream and user has swiped from the right edge to enter the glanceable
- * hub UI. From this state, the user can swipe from the left edge to go back to the lock screen
- * or dream, as well as swipe down for the notifications and up for the bouncer.
+ * Device is on the lockscreen and user has swiped from the right edge to enter the glanceable
+ * hub UI. From this state, the user can swipe from the left edge to go back to the lock screen,
+ * as well as swipe down for the notifications and up for the bouncer.
*/
GLANCEABLE_HUB {
@Override
@@ -310,6 +310,25 @@
mBehindAlpha = 0;
mNotifAlpha = 0;
mFrontAlpha = 0;
+
+ mFrontTint = Color.TRANSPARENT;
+ mBehindTint = mBackgroundColor;
+ mNotifTint = mClipQsScrim ? mBackgroundColor : Color.TRANSPARENT;
+ }
+ },
+
+ /**
+ * Device is dreaming and user has swiped from the right edge to enter the glanceable hub UI.
+ * From this state, the user can swipe from the left edge to go back to the dream, as well as
+ * swipe down for the notifications and up for the bouncer.
+ *
+ * This is a separate state from {@link #GLANCEABLE_HUB} because the scrims behave differently
+ * when the dream is running.
+ */
+ GLANCEABLE_HUB_OVER_DREAM {
+ @Override
+ public void prepare(ScrimState previousState) {
+ GLANCEABLE_HUB.prepare(previousState);
}
};
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 efdce06..016ba5f 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 @@
@Inject
constructor(
broadcastDispatcher: BroadcastDispatcher,
- private val carrierConfigManager: CarrierConfigManager,
+ private val carrierConfigManager: CarrierConfigManager?,
dumpManager: DumpManager,
logger: MobileInputLogger,
@Application scope: CoroutineScope,
@@ -87,7 +87,7 @@
.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 @@
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 859e636..213324a 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 @@
* 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 f64d4c6..d120a1b 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 @@
/** 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 43905c5..5c5b17e 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 @@
@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 5c53ff9..ac1d280 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.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.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 @@
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 @@
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 @@
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 a925e38..f755feb 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.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 @@
@Inject
public CarrierConfigTracker(
- CarrierConfigManager carrierConfigManager,
+ @Nullable CarrierConfigManager carrierConfigManager,
BroadcastDispatcher broadcastDispatcher) {
mCarrierConfigManager = carrierConfigManager;
IntentFilter filter = new IntentFilter();
@@ -95,6 +96,9 @@
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 deec215..c3274477 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 @@
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 @@
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 @@
}
}
+ @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 @@
@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 @@
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 @@
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/accessibility/floatingmenu/MenuViewLayerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
index 3862b0f..de795a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
@@ -61,6 +61,7 @@
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.util.ArraySet;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowManager;
@@ -71,6 +72,7 @@
import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.test.filters.SmallTest;
+import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.internal.accessibility.dialog.AccessibilityTarget;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.systemui.Flags;
@@ -220,6 +222,24 @@
}
@Test
+ @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
+ public void triggerDismissMenuAction_callsA11yManagerEnableShortcutsForTargets() {
+ final List<String> stubShortcutTargets = new ArrayList<>();
+ stubShortcutTargets.add(TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString());
+ when(mStubAccessibilityManager.getAccessibilityShortcutTargets(
+ AccessibilityManager.ACCESSIBILITY_BUTTON)).thenReturn(stubShortcutTargets);
+
+ mMenuViewLayer.mDismissMenuAction.run();
+
+ verify(mStubAccessibilityManager).enableShortcutsForTargets(
+ /* enable= */ false,
+ ShortcutConstants.UserShortcutType.SOFTWARE,
+ new ArraySet<>(stubShortcutTargets),
+ mSecureSettings.getRealUserHandle(UserHandle.USER_CURRENT));
+ }
+
+ @Test
+ @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
public void triggerDismissMenuAction_matchA11yButtonTargetsResult() {
mMenuViewLayer.mDismissMenuAction.run();
verify(mSecureSettings).putStringForUser(
@@ -228,6 +248,7 @@
}
@Test
+ @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
public void triggerDismissMenuAction_matchEnabledA11yServicesResult() {
setupEnabledAccessibilityServiceList();
@@ -239,6 +260,7 @@
}
@Test
+ @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
public void triggerDismissMenuAction_hasHardwareKeyShortcut_keepEnabledStatus() {
setupEnabledAccessibilityServiceList();
final List<String> stubShortcutTargets = new ArrayList<>();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt
index 54d6b53..67ca9a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt
@@ -20,6 +20,7 @@
import com.android.systemui.SysUITestComponent
import com.android.systemui.SysUITestModule
import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FakeFeatureFlagsClassicModule
import com.android.systemui.flags.Flags
@@ -45,6 +46,7 @@
[
SysUITestModule::class,
UserDomainLayerModule::class,
+ BiometricsDomainLayerModule::class,
]
)
interface TestComponent : SysUITestComponent<AuthDialogPanelInteractionDetector> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt
index dc438d7..7808c41 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt
@@ -84,8 +84,8 @@
val sensorType by collectLastValue(repository.sensorType)
val sensorLocations by collectLastValue(repository.sensorLocations)
- // Assert default properties.
- assertThat(sensorId).isEqualTo(-1)
+ // Assert non-initialized properties.
+ assertThat(sensorId).isEqualTo(-2)
assertThat(strength).isEqualTo(SensorStrength.CONVENIENCE)
assertThat(sensorType).isEqualTo(FingerprintSensorType.UNKNOWN)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DefaultUdfpsTouchOverlayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DefaultUdfpsTouchOverlayViewModelTest.kt
index fa17672..5caa146 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DefaultUdfpsTouchOverlayViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DefaultUdfpsTouchOverlayViewModelTest.kt
@@ -21,6 +21,7 @@
import com.android.systemui.SysUITestModule
import com.android.systemui.SysuiTestCase
import com.android.systemui.TestMocksModule
+import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
import com.android.systemui.collectLastValue
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FakeFeatureFlagsClassicModule
@@ -65,6 +66,7 @@
[
SysUITestModule::class,
UserDomainLayerModule::class,
+ BiometricsDomainLayerModule::class,
]
)
interface TestComponent : SysUITestComponent<DefaultUdfpsTouchOverlayViewModel> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorTest.kt
index e8eda80..d5839b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorTest.kt
@@ -21,9 +21,15 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
+import com.android.systemui.biometrics.data.repository.fakeFingerprintPropertyRepository
+import com.android.systemui.biometrics.domain.interactor.fingerprintPropertyInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
@@ -35,6 +41,8 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
class DeviceEntryUdfpsInteractorTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
private lateinit var fingerprintPropertyRepository: FakeFingerprintPropertyRepository
private lateinit var fingerprintAuthRepository: FakeDeviceEntryFingerprintAuthRepository
private lateinit var biometricsRepository: FakeBiometricSettingsRepository
@@ -43,77 +51,85 @@
@Before
fun setUp() {
- fingerprintPropertyRepository = FakeFingerprintPropertyRepository()
- fingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository()
- biometricsRepository = FakeBiometricSettingsRepository()
+ fingerprintPropertyRepository = kosmos.fakeFingerprintPropertyRepository
+ fingerprintAuthRepository = kosmos.fakeDeviceEntryFingerprintAuthRepository
+ biometricsRepository = kosmos.fakeBiometricSettingsRepository
underTest =
DeviceEntryUdfpsInteractor(
- fingerprintPropertyRepository = fingerprintPropertyRepository,
+ fingerprintPropertyInteractor = kosmos.fingerprintPropertyInteractor,
fingerprintAuthRepository = fingerprintAuthRepository,
biometricSettingsRepository = biometricsRepository,
)
}
@Test
- fun udfpsSupported_rearFp_false() = runTest {
- val isUdfpsSupported by collectLastValue(underTest.isUdfpsSupported)
- fingerprintPropertyRepository.supportsRearFps()
- assertThat(isUdfpsSupported).isFalse()
- }
+ fun udfpsSupported_rearFp_false() =
+ testScope.runTest {
+ val isUdfpsSupported by collectLastValue(underTest.isUdfpsSupported)
+ fingerprintPropertyRepository.supportsRearFps()
+ assertThat(isUdfpsSupported).isFalse()
+ }
@Test
- fun udfpsSupoprted() = runTest {
- val isUdfpsSupported by collectLastValue(underTest.isUdfpsSupported)
- fingerprintPropertyRepository.supportsUdfps()
- assertThat(isUdfpsSupported).isTrue()
- }
+ fun udfpsSupoprted() =
+ testScope.runTest {
+ val isUdfpsSupported by collectLastValue(underTest.isUdfpsSupported)
+ fingerprintPropertyRepository.supportsUdfps()
+ assertThat(isUdfpsSupported).isTrue()
+ }
@Test
- fun udfpsEnrolledAndEnabled() = runTest {
- val isUdfpsEnrolledAndEnabled by collectLastValue(underTest.isUdfpsEnrolledAndEnabled)
- fingerprintPropertyRepository.supportsUdfps()
- biometricsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
- assertThat(isUdfpsEnrolledAndEnabled).isTrue()
- }
+ fun udfpsEnrolledAndEnabled() =
+ testScope.runTest {
+ val isUdfpsEnrolledAndEnabled by collectLastValue(underTest.isUdfpsEnrolledAndEnabled)
+ fingerprintPropertyRepository.supportsUdfps()
+ biometricsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
+ assertThat(isUdfpsEnrolledAndEnabled).isTrue()
+ }
@Test
- fun udfpsEnrolledAndEnabled_rearFp_false() = runTest {
- val isUdfpsEnrolledAndEnabled by collectLastValue(underTest.isUdfpsEnrolledAndEnabled)
- fingerprintPropertyRepository.supportsRearFps()
- biometricsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
- assertThat(isUdfpsEnrolledAndEnabled).isFalse()
- }
+ fun udfpsEnrolledAndEnabled_rearFp_false() =
+ testScope.runTest {
+ val isUdfpsEnrolledAndEnabled by collectLastValue(underTest.isUdfpsEnrolledAndEnabled)
+ fingerprintPropertyRepository.supportsRearFps()
+ biometricsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
+ assertThat(isUdfpsEnrolledAndEnabled).isFalse()
+ }
@Test
- fun udfpsEnrolledAndEnabled_notEnrolledOrEnabled_false() = runTest {
- val isUdfpsEnrolledAndEnabled by collectLastValue(underTest.isUdfpsEnrolledAndEnabled)
- fingerprintPropertyRepository.supportsUdfps()
- biometricsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
- assertThat(isUdfpsEnrolledAndEnabled).isFalse()
- }
+ fun udfpsEnrolledAndEnabled_notEnrolledOrEnabled_false() =
+ testScope.runTest {
+ val isUdfpsEnrolledAndEnabled by collectLastValue(underTest.isUdfpsEnrolledAndEnabled)
+ fingerprintPropertyRepository.supportsUdfps()
+ biometricsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+ assertThat(isUdfpsEnrolledAndEnabled).isFalse()
+ }
@Test
- fun isListeningForUdfps() = runTest {
- val isListeningForUdfps by collectLastValue(underTest.isListeningForUdfps)
- fingerprintPropertyRepository.supportsUdfps()
- fingerprintAuthRepository.setIsRunning(true)
- assertThat(isListeningForUdfps).isTrue()
- }
+ fun isListeningForUdfps() =
+ testScope.runTest {
+ val isListeningForUdfps by collectLastValue(underTest.isListeningForUdfps)
+ fingerprintPropertyRepository.supportsUdfps()
+ fingerprintAuthRepository.setIsRunning(true)
+ assertThat(isListeningForUdfps).isTrue()
+ }
@Test
- fun isListeningForUdfps_rearFp_false() = runTest {
- val isListeningForUdfps by collectLastValue(underTest.isListeningForUdfps)
- fingerprintPropertyRepository.supportsRearFps()
- fingerprintAuthRepository.setIsRunning(true)
- assertThat(isListeningForUdfps).isFalse()
- }
+ fun isListeningForUdfps_rearFp_false() =
+ testScope.runTest {
+ val isListeningForUdfps by collectLastValue(underTest.isListeningForUdfps)
+ fingerprintPropertyRepository.supportsRearFps()
+ fingerprintAuthRepository.setIsRunning(true)
+ assertThat(isListeningForUdfps).isFalse()
+ }
@Test
- fun isListeningForUdfps_notRunning_false() = runTest {
- val isListeningForUdfps by collectLastValue(underTest.isListeningForUdfps)
- fingerprintPropertyRepository.supportsUdfps()
- fingerprintAuthRepository.setIsRunning(false)
- assertThat(isListeningForUdfps).isFalse()
- }
+ fun isListeningForUdfps_notRunning_false() =
+ testScope.runTest {
+ val isListeningForUdfps by collectLastValue(underTest.isListeningForUdfps)
+ fingerprintPropertyRepository.supportsUdfps()
+ fingerprintAuthRepository.setIsRunning(false)
+ assertThat(isListeningForUdfps).isFalse()
+ }
}
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 0bd4cbe..1849245 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.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 @@
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 @@
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 @@
mSystemSettings,
mSystemClock,
mDispatcher,
- () -> mDreamingToLockscreenTransitionViewModel,
+ () -> mDreamViewModel,
mSystemPropertiesHelper,
() -> mock(WindowManagerLockscreenVisibilityManager.class),
mSelectedUserInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryTest.kt
index 37836a5..bcaad01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryTest.kt
@@ -62,7 +62,6 @@
whenever(defaultLockscreenBlueprint.id).thenReturn(DEFAULT)
underTest =
KeyguardBlueprintRepository(
- configurationRepository,
setOf(defaultLockscreenBlueprint),
fakeExecutorHandler,
threadAssert,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt
index b0d8de3..170d348 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt
@@ -21,95 +21,80 @@
import androidx.test.filters.SmallTest
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
-import com.android.systemui.keyguard.data.repository.KeyguardBlueprintRepository
+import com.android.systemui.biometrics.data.repository.fakeFingerprintPropertyRepository
+import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.fakeKeyguardClockRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor.Companion.SPLIT_SHADE_WEATHER_CLOCK_BLUEPRINT_ID
import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor.Companion.WEATHER_CLOCK_BLUEPRINT_ID
import com.android.systemui.keyguard.ui.view.layout.blueprints.DefaultKeyguardBlueprint
import com.android.systemui.keyguard.ui.view.layout.blueprints.SplitShadeKeyguardBlueprint
-import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition
-import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Config
-import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Type
+import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.clocks.ClockConfig
import com.android.systemui.plugins.clocks.ClockController
-import com.android.systemui.statusbar.policy.SplitShadeStateController
-import com.android.systemui.util.mockito.any
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.whenever
-import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.TestScope
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
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.Mock
-import org.mockito.Mockito.never
-import org.mockito.Mockito.reset
-import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
+@ExperimentalCoroutinesApi
@SmallTest
@RunWith(AndroidJUnit4::class)
class KeyguardBlueprintInteractorTest : SysuiTestCase() {
- private val configurationFlow = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
- private lateinit var underTest: KeyguardBlueprintInteractor
- private lateinit var testScope: TestScope
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private val underTest by lazy { kosmos.keyguardBlueprintInteractor }
+ private val clockRepository by lazy { kosmos.fakeKeyguardClockRepository }
+ private val configurationRepository by lazy { kosmos.fakeConfigurationRepository }
+ private val fingerprintPropertyRepository by lazy { kosmos.fakeFingerprintPropertyRepository }
- val refreshTransition: MutableSharedFlow<IntraBlueprintTransition.Config> =
- MutableSharedFlow(extraBufferCapacity = 1)
-
- @Mock private lateinit var splitShadeStateController: SplitShadeStateController
- @Mock private lateinit var keyguardBlueprintRepository: KeyguardBlueprintRepository
- @Mock private lateinit var clockInteractor: KeyguardClockInteractor
@Mock private lateinit var clockController: ClockController
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
- testScope = TestScope(StandardTestDispatcher())
- whenever(keyguardBlueprintRepository.configurationChange).thenReturn(configurationFlow)
- whenever(keyguardBlueprintRepository.refreshTransition).thenReturn(refreshTransition)
- whenever(clockInteractor.currentClock).thenReturn(MutableStateFlow(clockController))
- clockInteractor.currentClock
-
- underTest =
- KeyguardBlueprintInteractor(
- keyguardBlueprintRepository,
- testScope.backgroundScope,
- mContext,
- splitShadeStateController,
- clockInteractor,
- )
}
@Test
fun testAppliesDefaultBlueprint() {
testScope.runTest {
- whenever(splitShadeStateController.shouldUseSplitNotificationShade(any()))
- .thenReturn(false)
-
- reset(keyguardBlueprintRepository)
- configurationFlow.tryEmit(Unit)
+ val blueprint by collectLastValue(underTest.blueprint)
+ overrideResource(R.bool.config_use_split_notification_shade, false)
+ configurationRepository.onConfigurationChange()
runCurrent()
- verify(keyguardBlueprintRepository)
- .applyBlueprint(DefaultKeyguardBlueprint.Companion.DEFAULT)
+ assertThat(blueprint?.id).isEqualTo(DefaultKeyguardBlueprint.Companion.DEFAULT)
}
}
@Test
fun testAppliesSplitShadeBlueprint() {
testScope.runTest {
- whenever(splitShadeStateController.shouldUseSplitNotificationShade(any()))
- .thenReturn(true)
-
- reset(keyguardBlueprintRepository)
- configurationFlow.tryEmit(Unit)
+ val blueprint by collectLastValue(underTest.blueprint)
+ overrideResource(R.bool.config_use_split_notification_shade, true)
+ configurationRepository.onConfigurationChange()
runCurrent()
- verify(keyguardBlueprintRepository)
- .applyBlueprint(SplitShadeKeyguardBlueprint.Companion.ID)
+ assertThat(blueprint?.id).isEqualTo(SplitShadeKeyguardBlueprint.Companion.ID)
+ }
+ }
+
+ @Test
+ fun fingerprintPropertyInitialized_updatesBlueprint() {
+ testScope.runTest {
+ val blueprint by collectLastValue(underTest.blueprint)
+ overrideResource(R.bool.config_use_split_notification_shade, true)
+ fingerprintPropertyRepository.supportsUdfps() // initialize properties
+ runCurrent()
+ assertThat(blueprint?.id).isEqualTo(SplitShadeKeyguardBlueprint.Companion.ID)
}
}
@@ -117,6 +102,7 @@
fun composeLockscreenOff_DoesAppliesSplitShadeWeatherClockBlueprint() {
testScope.runTest {
mSetFlagsRule.disableFlags(Flags.FLAG_COMPOSE_LOCKSCREEN)
+ val blueprint by collectLastValue(underTest.blueprint)
whenever(clockController.config)
.thenReturn(
ClockConfig(
@@ -125,15 +111,12 @@
description = "clock",
)
)
- whenever(splitShadeStateController.shouldUseSplitNotificationShade(any()))
- .thenReturn(true)
-
- reset(keyguardBlueprintRepository)
- configurationFlow.tryEmit(Unit)
+ clockRepository.setCurrentClock(clockController)
+ overrideResource(R.bool.config_use_split_notification_shade, true)
+ configurationRepository.onConfigurationChange()
runCurrent()
- verify(keyguardBlueprintRepository, never())
- .applyBlueprint(SPLIT_SHADE_WEATHER_CLOCK_BLUEPRINT_ID)
+ assertThat(blueprint?.id).isNotEqualTo(SPLIT_SHADE_WEATHER_CLOCK_BLUEPRINT_ID)
}
}
@@ -141,6 +124,7 @@
fun testDoesAppliesSplitShadeWeatherClockBlueprint() {
testScope.runTest {
mSetFlagsRule.enableFlags(Flags.FLAG_COMPOSE_LOCKSCREEN)
+ val blueprint by collectLastValue(underTest.blueprint)
whenever(clockController.config)
.thenReturn(
ClockConfig(
@@ -149,15 +133,12 @@
description = "clock",
)
)
- whenever(splitShadeStateController.shouldUseSplitNotificationShade(any()))
- .thenReturn(true)
-
- reset(keyguardBlueprintRepository)
- configurationFlow.tryEmit(Unit)
+ clockRepository.setCurrentClock(clockController)
+ overrideResource(R.bool.config_use_split_notification_shade, true)
+ configurationRepository.onConfigurationChange()
runCurrent()
- verify(keyguardBlueprintRepository)
- .applyBlueprint(SPLIT_SHADE_WEATHER_CLOCK_BLUEPRINT_ID)
+ assertThat(blueprint?.id).isEqualTo(SPLIT_SHADE_WEATHER_CLOCK_BLUEPRINT_ID)
}
}
@@ -165,6 +146,7 @@
fun testAppliesWeatherClockBlueprint() {
testScope.runTest {
mSetFlagsRule.enableFlags(Flags.FLAG_COMPOSE_LOCKSCREEN)
+ val blueprint by collectLastValue(underTest.blueprint)
whenever(clockController.config)
.thenReturn(
ClockConfig(
@@ -173,33 +155,12 @@
description = "clock",
)
)
- whenever(splitShadeStateController.shouldUseSplitNotificationShade(any()))
- .thenReturn(false)
-
- reset(keyguardBlueprintRepository)
- configurationFlow.tryEmit(Unit)
+ clockRepository.setCurrentClock(clockController)
+ overrideResource(R.bool.config_use_split_notification_shade, false)
+ configurationRepository.onConfigurationChange()
runCurrent()
- verify(keyguardBlueprintRepository).applyBlueprint(WEATHER_CLOCK_BLUEPRINT_ID)
+ assertThat(blueprint?.id).isEqualTo(WEATHER_CLOCK_BLUEPRINT_ID)
}
}
-
- @Test
- fun testRefreshBlueprint() {
- underTest.refreshBlueprint()
- verify(keyguardBlueprintRepository).refreshBlueprint()
- }
-
- @Test
- fun testTransitionToBlueprint() {
- underTest.transitionToBlueprint("abc")
- verify(keyguardBlueprintRepository).applyBlueprint("abc")
- }
-
- @Test
- fun testRefreshBlueprintWithTransition() {
- underTest.refreshBlueprint(Type.DefaultTransition)
- verify(keyguardBlueprintRepository)
- .refreshBlueprint(Config(Type.DefaultTransition, true, true))
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySectionTest.kt
index 699284e..09c56b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySectionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySectionTest.kt
@@ -22,7 +22,6 @@
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.test.filters.SmallTest
-import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.LockIconViewController
import com.android.systemui.Flags as AConfigFlags
import com.android.systemui.SysuiTestCase
@@ -37,8 +36,10 @@
import com.android.systemui.res.R
import com.android.systemui.shade.NotificationPanelView
import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.TestScope
import org.junit.Before
import org.junit.Test
@@ -53,13 +54,13 @@
@RunWith(JUnit4::class)
@SmallTest
class DefaultDeviceEntrySectionTest : SysuiTestCase() {
- @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
@Mock private lateinit var authController: AuthController
@Mock(answer = Answers.RETURNS_DEEP_STUBS) private lateinit var windowManager: WindowManager
@Mock private lateinit var notificationPanelView: NotificationPanelView
private lateinit var featureFlags: FakeFeatureFlags
@Mock private lateinit var lockIconViewController: LockIconViewController
@Mock private lateinit var falsingManager: FalsingManager
+ @Mock private lateinit var deviceEntryIconViewModel: DeviceEntryIconViewModel
private lateinit var underTest: DefaultDeviceEntrySection
@Before
@@ -73,14 +74,13 @@
underTest =
DefaultDeviceEntrySection(
TestScope().backgroundScope,
- keyguardUpdateMonitor,
authController,
windowManager,
context,
notificationPanelView,
featureFlags,
{ lockIconViewController },
- { mock(DeviceEntryIconViewModel::class.java) },
+ { deviceEntryIconViewModel },
{ mock(DeviceEntryForegroundViewModel::class.java) },
{ mock(DeviceEntryBackgroundViewModel::class.java) },
{ falsingManager },
@@ -129,6 +129,7 @@
@Test
fun applyConstraints_udfps_refactor_on() {
mSetFlagsRule.enableFlags(AConfigFlags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
+ whenever(deviceEntryIconViewModel.isUdfpsSupported).thenReturn(MutableStateFlow(false))
val cs = ConstraintSet()
underTest.applyConstraints(cs)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt
index ada93db..2e8160b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt
@@ -37,7 +37,6 @@
import com.android.systemui.model.SysUiState
import com.android.systemui.qs.tiles.RecordIssueTile
import com.android.systemui.res.R
-import com.android.systemui.settings.UserContextProvider
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.phone.SystemUIDialog
@@ -71,12 +70,11 @@
@Mock private lateinit var devicePolicyResolver: ScreenCaptureDevicePolicyResolver
@Mock private lateinit var dprLazy: dagger.Lazy<ScreenCaptureDevicePolicyResolver>
@Mock private lateinit var mediaProjectionMetricsLogger: MediaProjectionMetricsLogger
- @Mock private lateinit var userContextProvider: UserContextProvider
@Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var userFileManager: UserFileManager
@Mock private lateinit var sharedPreferences: SharedPreferences
- @Mock private lateinit var screenCaptureDisabledDialogDelegate:
- ScreenCaptureDisabledDialogDelegate
+ @Mock
+ private lateinit var screenCaptureDisabledDialogDelegate: ScreenCaptureDisabledDialogDelegate
@Mock private lateinit var screenCaptureDisabledDialog: SystemUIDialog
@Mock private lateinit var sysuiState: SysUiState
@@ -96,9 +94,8 @@
MockitoAnnotations.initMocks(this)
whenever(dprLazy.get()).thenReturn(devicePolicyResolver)
whenever(sysuiState.setFlag(anyInt(), anyBoolean())).thenReturn(sysuiState)
- whenever(userContextProvider.userContext).thenReturn(mContext)
whenever(screenCaptureDisabledDialogDelegate.createDialog())
- .thenReturn(screenCaptureDisabledDialog)
+ .thenReturn(screenCaptureDisabledDialog)
whenever(
userFileManager.getSharedPreferences(
eq(RecordIssueTile.TILE_SPEC),
@@ -123,7 +120,6 @@
dialog =
RecordIssueDialogDelegate(
factory,
- userContextProvider,
userTracker,
flags,
bgExecutor,
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 3dc9037..0baee5d 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 @@
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 @@
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 62d2d0e..07d9350 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.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 @@
@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 @@
GlanceableHubContainerController(
communalInteractor,
communalViewModel,
+ dialogFactory,
keyguardTransitionInteractor,
shadeInteractor,
powerManager
@@ -138,6 +141,7 @@
GlanceableHubContainerController(
communalInteractor,
communalViewModel,
+ dialogFactory,
keyguardTransitionInteractor,
shadeInteractor,
powerManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index cdff4d1..43fcdf3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -38,6 +38,7 @@
import static org.mockito.Mockito.when;
import static kotlinx.coroutines.flow.FlowKt.emptyFlow;
+import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;
import android.annotation.IdRes;
import android.content.ContentResolver;
@@ -213,7 +214,6 @@
import java.util.Optional;
import kotlinx.coroutines.CoroutineDispatcher;
-import kotlinx.coroutines.flow.StateFlowKt;
import kotlinx.coroutines.test.TestScope;
public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
@@ -409,10 +409,10 @@
new ShadeAnimationRepository(), mShadeRepository);
mPowerInteractor = keyguardInteractorDeps.getPowerInteractor();
when(mKeyguardTransitionInteractor.isInTransitionToStateWhere(any())).thenReturn(
- StateFlowKt.MutableStateFlow(false));
+ MutableStateFlow(false));
DeviceEntryUdfpsInteractor deviceEntryUdfpsInteractor =
mock(DeviceEntryUdfpsInteractor.class);
- when(deviceEntryUdfpsInteractor.isUdfpsSupported()).thenReturn(emptyFlow());
+ when(deviceEntryUdfpsInteractor.isUdfpsSupported()).thenReturn(MutableStateFlow(false));
mShadeInteractor = new ShadeInteractorImpl(
mTestScope.getBackgroundScope(),
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 d24fe1b..6d5d5be 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 @@
// 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 @@
// 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/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
index 3808d30..c31c625 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
@@ -36,7 +36,7 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
-import static kotlinx.coroutines.flow.FlowKt.emptyFlow;
+import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;
import android.app.IActivityManager;
import android.content.pm.ActivityInfo;
@@ -205,7 +205,7 @@
DeviceEntryUdfpsInteractor deviceEntryUdfpsInteractor =
mock(DeviceEntryUdfpsInteractor.class);
- when(deviceEntryUdfpsInteractor.isUdfpsSupported()).thenReturn(emptyFlow());
+ when(deviceEntryUdfpsInteractor.isUdfpsSupported()).thenReturn(MutableStateFlow(false));
mShadeInteractor = new ShadeInteractorImpl(
mTestScope.getBackgroundScope(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
index 4809a47..a077164 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
@@ -22,7 +22,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static kotlinx.coroutines.flow.FlowKt.emptyFlow;
+import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;
import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher;
import android.content.res.Resources;
@@ -234,7 +234,8 @@
DeviceEntryUdfpsInteractor deviceEntryUdfpsInteractor =
mock(DeviceEntryUdfpsInteractor.class);
- when(deviceEntryUdfpsInteractor.isUdfpsSupported()).thenReturn(emptyFlow());
+ when(deviceEntryUdfpsInteractor.isUdfpsSupported()).thenReturn(
+ MutableStateFlow(false));
mShadeInteractor = new ShadeInteractorImpl(
mTestScope.getBackgroundScope(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
index 2f957b0..0a9541a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
@@ -18,7 +18,7 @@
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testScope
-import com.android.systemui.scene.domain.interactor.PanelExpansionInteractor
+import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.FakeSceneDataSource
@@ -27,8 +27,8 @@
import com.android.systemui.shade.STATE_OPENING
import com.android.systemui.shade.ShadeExpansionChangeEvent
import com.android.systemui.shade.ShadeExpansionStateManager
+import com.android.systemui.shade.domain.interactor.panelExpansionInteractor
import com.android.systemui.statusbar.SysuiStatusBarStateController
-import com.android.systemui.statusbar.notification.stack.ui.viewmodel.panelExpansionInteractor
import com.android.systemui.statusbar.policy.FakeConfigurationController
import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.testKosmos
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
index 86116a0..d35c7dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -9,6 +9,7 @@
import com.android.systemui.SysUITestModule
import com.android.systemui.SysuiTestCase
import com.android.systemui.TestMocksModule
+import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
import com.android.systemui.classifier.FalsingCollectorFake
import com.android.systemui.classifier.FalsingManagerFake
import com.android.systemui.dagger.SysUISingleton
@@ -35,6 +36,8 @@
import com.android.systemui.statusbar.policy.FakeConfigurationController
import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.user.domain.UserDomainLayerModule
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.mock
import dagger.BindsInstance
import dagger.Component
@@ -55,6 +58,7 @@
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.ArgumentMatchers.eq
+import org.mockito.ArgumentMatchers.isNull
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.clearInvocations
@@ -310,6 +314,17 @@
}
@Test
+ fun testGoToLockedShadeCancelDoesntLeaveShadeOpenOnKeyguardHide() {
+ whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false)
+ whenever(lockScreenUserManager.isLockscreenPublicMode(any())).thenReturn(true)
+ transitionController.goToLockedShade(null)
+ val captor = argumentCaptor<Runnable>()
+ verify(centralSurfaces).showBouncerWithDimissAndCancelIfKeyguard(isNull(), captor.capture())
+ captor.value.run()
+ verify(statusbarStateController).setLeaveOpenOnKeyguardHide(false)
+ }
+
+ @Test
fun testDragDownAmountDoesntCallOutInLockedDownShade() {
whenever(nsslController.isInLockedDownShade).thenReturn(true)
transitionController.dragDownAmount = 10f
@@ -611,6 +626,7 @@
[
SysUITestModule::class,
UserDomainLayerModule::class,
+ BiometricsDomainLayerModule::class,
]
)
interface TestComponent {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
index dfbb6ea..103dcb7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -54,6 +54,7 @@
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.LargeScreenHeaderHelper
import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -69,7 +70,7 @@
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals
@@ -85,9 +86,8 @@
import org.mockito.Mockito
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
-import com.android.systemui.scene.shared.model.Scenes
import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -155,7 +155,7 @@
{ kosmos.sceneInteractor },
)
- whenever(deviceEntryUdfpsInteractor.isUdfpsSupported).thenReturn(emptyFlow())
+ whenever(deviceEntryUdfpsInteractor.isUdfpsSupported).thenReturn(MutableStateFlow(false))
shadeInteractor =
ShadeInteractorImpl(
testScope.backgroundScope,
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 4519ba6..419b0fd 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.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 @@
@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 @@
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 115a0d3..34eeba0 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.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.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 @@
@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 @@
handler,
secureSettings,
lockscreenUserManager,
+ sensitiveNotifProtectionController,
sectionStyleProvider,
userTracker,
groupMembershipManager,
@@ -108,6 +113,19 @@
}
@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 @@
// 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/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 84156ee1..c8c54dbd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -859,6 +859,29 @@
}
@Test
+ public void testEnteringGlanceableHub_whenDreaming_updatesScrim() {
+ when(mKeyguardStateController.isShowing()).thenReturn(true);
+ when(mKeyguardStateController.isOccluded()).thenReturn(true);
+ when(mKeyguardUpdateMonitor.isDreaming()).thenReturn(true);
+
+ // Transition to the glanceable hub.
+ mCommunalRepository.setTransitionState(flowOf(new ObservableTransitionState.Idle(
+ CommunalScenes.Communal)));
+ mTestScope.getTestScheduler().runCurrent();
+
+ // ScrimState also transitions.
+ verify(mScrimController).transitionTo(ScrimState.GLANCEABLE_HUB_OVER_DREAM);
+
+ // Transition away from the glanceable hub.
+ mCommunalRepository.setTransitionState(flowOf(new ObservableTransitionState.Idle(
+ CommunalScenes.Blank)));
+ mTestScope.getTestScheduler().runCurrent();
+
+ // ScrimState goes back to UNLOCKED.
+ verify(mScrimController).transitionTo(eq(ScrimState.DREAMING));
+ }
+
+ @Test
public void testShowKeyguardImplementation_setsState() {
when(mLockscreenUserManager.getCurrentProfiles()).thenReturn(new SparseArray<>());
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 56fc7b9..1748cff 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 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 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,7 +229,22 @@
}
@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());
+ verify(mCommandQueue).addCallback(any());
+ verify(mStatusBarIconController).addIconGroup(any());
+ verify(mUserManager).isUserSwitcherEnabled(anyBoolean());
+ }
+
+ @Test
+ @DisableFlags(FLAG_UPDATE_USER_SWITCHER_BACKGROUND)
+ public void onViewAttached_updateUserSwitcherFlagDisabled_callbacksRegistered() {
mController.onViewAttached();
verify(mConfigurationController).addCallback(any());
@@ -238,7 +256,26 @@
}
@Test
- public void onConfigurationChanged_updatesUserSwitcherVisibility() {
+ @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 @@
}
@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 @@
verify(mStatusBarIconController).addIconGroup(any());
}
-
+
@Test
public void setBatteryListening_true_callbackAdded() {
mController.setBatteryListening(true);
@@ -762,6 +818,11 @@
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/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 99c2dc7..cdbbc93 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -794,6 +794,73 @@
}
@Test
+ public void transitionToHubOverDream() {
+ mScrimController.setRawPanelExpansionFraction(0f);
+ mScrimController.setBouncerHiddenFraction(KeyguardBouncerConstants.EXPANSION_HIDDEN);
+ mScrimController.transitionTo(ScrimState.GLANCEABLE_HUB_OVER_DREAM);
+ finishAnimationsImmediately();
+
+ // All scrims transparent on the hub.
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, TRANSPARENT,
+ mScrimBehind, TRANSPARENT));
+ }
+
+ @Test
+ public void openBouncerOnHubOverDream() {
+ mScrimController.transitionTo(ScrimState.GLANCEABLE_HUB_OVER_DREAM);
+
+ // Open the bouncer.
+ mScrimController.setRawPanelExpansionFraction(0f);
+ mScrimController.setBouncerHiddenFraction(KeyguardBouncerConstants.EXPANSION_VISIBLE);
+ finishAnimationsImmediately();
+
+ // Only behind widget is visible.
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, TRANSPARENT,
+ mScrimBehind, OPAQUE));
+
+ // Bouncer is closed.
+ mScrimController.setBouncerHiddenFraction(KeyguardBouncerConstants.EXPANSION_HIDDEN);
+ mScrimController.transitionTo(ScrimState.GLANCEABLE_HUB_OVER_DREAM);
+ finishAnimationsImmediately();
+
+ // All scrims are transparent.
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, TRANSPARENT,
+ mScrimBehind, TRANSPARENT));
+ }
+
+ @Test
+ public void openShadeOnHubOverDream() {
+ mScrimController.transitionTo(ScrimState.GLANCEABLE_HUB_OVER_DREAM);
+
+ // Open the shade.
+ mScrimController.transitionTo(SHADE_LOCKED);
+ mScrimController.setQsPosition(1f, 0);
+ mScrimController.setRawPanelExpansionFraction(1f);
+ finishAnimationsImmediately();
+
+ // Shade scrims are visible.
+ assertScrimAlpha(Map.of(
+ mNotificationsScrim, OPAQUE,
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE));
+
+ mScrimController.transitionTo(ScrimState.GLANCEABLE_HUB_OVER_DREAM);
+ finishAnimationsImmediately();
+
+ // All scrims are transparent.
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, TRANSPARENT,
+ mScrimBehind, TRANSPARENT));
+ }
+
+ @Test
public void onThemeChange_bouncerBehindTint_isUpdatedToSurfaceColor() {
assertEquals(BOUNCER.getBehindTint(), 0x112233);
mSurfaceColor = 0x223344;
@@ -1432,7 +1499,8 @@
ScrimState.UNINITIALIZED, ScrimState.KEYGUARD, BOUNCER,
ScrimState.DREAMING, ScrimState.BOUNCER_SCRIMMED, ScrimState.BRIGHTNESS_MIRROR,
ScrimState.UNLOCKED, SHADE_LOCKED, ScrimState.AUTH_SCRIMMED,
- ScrimState.AUTH_SCRIMMED_SHADE, ScrimState.GLANCEABLE_HUB));
+ ScrimState.AUTH_SCRIMMED_SHADE, ScrimState.GLANCEABLE_HUB,
+ ScrimState.GLANCEABLE_HUB_OVER_DREAM));
for (ScrimState state : ScrimState.values()) {
if (!lowPowerModeStates.contains(state) && !regularStates.contains(state)) {
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 e499a3c..e4a1c26 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 @@
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 d0261ae..974e396 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_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.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 @@
}
@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/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index c0d3d27..19f31d5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -50,7 +50,7 @@
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
-import static kotlinx.coroutines.flow.FlowKt.emptyFlow;
+import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;
import android.app.ActivityManager;
import android.app.IActivityManager;
@@ -452,7 +452,7 @@
DeviceEntryUdfpsInteractor deviceEntryUdfpsInteractor =
mock(DeviceEntryUdfpsInteractor.class);
- when(deviceEntryUdfpsInteractor.isUdfpsSupported()).thenReturn(emptyFlow());
+ when(deviceEntryUdfpsInteractor.isUdfpsSupported()).thenReturn(MutableStateFlow(false));
mShadeInteractor =
new ShadeInteractorImpl(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/android/os/LooperKosmos.kt
similarity index 60%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt
copy to packages/SystemUI/tests/utils/src/android/os/LooperKosmos.kt
index a025846..a8ca9bfc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/android/os/LooperKosmos.kt
@@ -14,17 +14,15 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.notification.stack.ui.viewmodel
+package android.os
+import android.testing.TestableLooper
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.scene.domain.interactor.PanelExpansionInteractor
-import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.shade.data.repository.shadeRepository
+import com.android.systemui.kosmos.testCase
-val Kosmos.panelExpansionInteractor by Fixture {
- PanelExpansionInteractor(
- sceneInteractor = sceneInteractor,
- shadeRepository = shadeRepository,
- )
+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/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/animation/DialogTransitionAnimatorKosmos.kt
similarity index 60%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/animation/DialogTransitionAnimatorKosmos.kt
index a025846..ed291d1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/animation/DialogTransitionAnimatorKosmos.kt
@@ -14,17 +14,9 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.notification.stack.ui.viewmodel
+package com.android.systemui.animation
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.scene.domain.interactor.PanelExpansionInteractor
-import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.shade.data.repository.shadeRepository
-val Kosmos.panelExpansionInteractor by Fixture {
- PanelExpansionInteractor(
- sceneInteractor = sceneInteractor,
- shadeRepository = shadeRepository,
- )
-}
+val Kosmos.dialogTransitionAnimator by Fixture { fakeDialogTransitionAnimator() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt
index 1b951d9..9765d53 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt
@@ -19,12 +19,17 @@
import android.util.Size
import com.android.systemui.biometrics.shared.model.DisplayRotation
+import com.android.systemui.dagger.SysUISingleton
+import dagger.Binds
+import dagger.Module
+import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
-class FakeDisplayStateRepository : DisplayStateRepository {
+@SysUISingleton
+class FakeDisplayStateRepository @Inject constructor() : DisplayStateRepository {
private val _isInRearDisplayMode = MutableStateFlow<Boolean>(false)
override val isInRearDisplayMode: StateFlow<Boolean> = _isInRearDisplayMode.asStateFlow()
@@ -51,3 +56,8 @@
_currentDisplaySize.value = size
}
}
+
+@Module
+interface FakeDisplayStateRepositoryModule {
+ @Binds fun bindFake(fake: FakeDisplayStateRepository): DisplayStateRepository
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFingerprintPropertyRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFingerprintPropertyRepository.kt
index 005cac4..bd30fb4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFingerprintPropertyRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFingerprintPropertyRepository.kt
@@ -28,6 +28,7 @@
@SysUISingleton
class FakeFingerprintPropertyRepository @Inject constructor() : FingerprintPropertyRepository {
+ override val propertiesInitialized: MutableStateFlow<Boolean> = MutableStateFlow(false)
private val _sensorId: MutableStateFlow<Int> = MutableStateFlow(-1)
override val sensorId = _sensorId.asStateFlow()
@@ -54,6 +55,7 @@
_strength.value = strength
_sensorType.value = sensorType
_sensorLocations.value = sensorLocations
+ propertiesInitialized.value = true
}
/** setProperties as if the device supports UDFPS_OPTICAL. */
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt
index e262066..34a9c8a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt
@@ -21,9 +21,11 @@
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.applicationCoroutineScope
val Kosmos.fingerprintPropertyInteractor by Fixture {
FingerprintPropertyInteractor(
+ applicationScope = applicationCoroutineScope,
context = applicationContext,
repository = fingerprintPropertyRepository,
configurationInteractor = configurationInteractor,
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 050c2c9..4d74254c 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 @@
@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 6ac702e..8866fd3 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.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 @@
val Kosmos.communalInteractor by Fixture {
CommunalInteractor(
applicationScope = applicationCoroutineScope,
+ broadcastDispatcher = broadcastDispatcher,
communalRepository = communalRepository,
widgetRepository = communalWidgetRepository,
mediaRepository = communalMediaRepository,
@@ -48,6 +52,8 @@
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/deviceentry/data/FakeDeviceEntryDataLayerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/FakeDeviceEntryDataLayerModule.kt
index 8ff04a63..1c8190e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/FakeDeviceEntryDataLayerModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/FakeDeviceEntryDataLayerModule.kt
@@ -15,8 +15,10 @@
package com.android.systemui.deviceentry.data
+import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepositoryModule
import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepositoryModule
import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepositoryModule
+import com.android.systemui.display.data.repository.FakeDisplayRepositoryModule
import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepositoryModule
import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepositoryModule
import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepositoryModule
@@ -30,6 +32,8 @@
FakeDeviceEntryRepositoryModule::class,
FakeDeviceEntryFaceAuthRepositoryModule::class,
FakeDeviceEntryFingerprintAuthRepositoryModule::class,
+ FakeDisplayRepositoryModule::class,
+ FakeDisplayStateRepositoryModule::class,
FakeFingerprintPropertyRepositoryModule::class,
FakeTrustRepositoryModule::class,
]
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorKosmos.kt
index b04161a..81123d0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorKosmos.kt
@@ -18,7 +18,7 @@
package com.android.systemui.deviceentry.domain.interactor
-import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
+import com.android.systemui.biometrics.domain.interactor.fingerprintPropertyInteractor
import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository
import com.android.systemui.kosmos.Kosmos
@@ -27,7 +27,7 @@
val Kosmos.deviceEntryUdfpsInteractor by Fixture {
DeviceEntryUdfpsInteractor(
- fingerprintPropertyRepository = fingerprintPropertyRepository,
+ fingerprintPropertyInteractor = fingerprintPropertyInteractor,
fingerprintAuthRepository = deviceEntryFingerprintAuthRepository,
biometricSettingsRepository = biometricSettingsRepository,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt
index d8098b7..0fc0a3c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt
@@ -16,7 +16,11 @@
package com.android.systemui.display.data.repository
import android.view.Display
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.util.mockito.mock
+import dagger.Binds
+import dagger.Module
+import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import org.mockito.Mockito.`when` as whenever
@@ -42,8 +46,9 @@
fun createPendingDisplay(id: Int = 0): DisplayRepository.PendingDisplay =
mock<DisplayRepository.PendingDisplay> { whenever(this.id).thenReturn(id) }
+@SysUISingleton
/** Fake [DisplayRepository] implementation for testing. */
-class FakeDisplayRepository : DisplayRepository {
+class FakeDisplayRepository @Inject constructor() : DisplayRepository {
private val flow = MutableSharedFlow<Set<Display>>(replay = 1)
private val pendingDisplayFlow =
MutableSharedFlow<DisplayRepository.PendingDisplay?>(replay = 1)
@@ -71,3 +76,8 @@
override val displayChangeEvent: Flow<Int> = _displayChangeEvent
suspend fun emitDisplayChangeEvent(displayId: Int) = _displayChangeEvent.emit(displayId)
}
+
+@Module
+interface FakeDisplayRepositoryModule {
+ @Binds fun bindFake(fake: FakeDisplayRepository): DisplayRepository
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt
index 592fa38..5b642ea 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt
@@ -42,7 +42,7 @@
private val _currentClockId = MutableStateFlow(DEFAULT_CLOCK_ID)
override val currentClockId: Flow<ClockId> = _currentClockId
- private val _currentClock = MutableStateFlow(null)
+ private val _currentClock: MutableStateFlow<ClockController?> = MutableStateFlow(null)
override val currentClock = _currentClock
private val _previewClockPair =
@@ -60,6 +60,10 @@
override fun setClockSize(@ClockSize size: Int) {
_clockSize.value = size
}
+
+ fun setCurrentClock(clockController: ClockController) {
+ _currentClock.value = clockController
+ }
}
@Module
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt
index 8452963..75489b6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt
@@ -17,10 +17,12 @@
package com.android.systemui.keyguard.data.repository
import android.os.fakeExecutorHandler
-import com.android.systemui.common.ui.data.repository.configurationRepository
+import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor.Companion.SPLIT_SHADE_WEATHER_CLOCK_BLUEPRINT_ID
+import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor.Companion.WEATHER_CLOCK_BLUEPRINT_ID
import com.android.systemui.keyguard.shared.model.KeyguardBlueprint
import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.keyguard.ui.view.layout.blueprints.DefaultKeyguardBlueprint.Companion.DEFAULT
+import com.android.systemui.keyguard.ui.view.layout.blueprints.SplitShadeKeyguardBlueprint
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.util.ThreadAssert
import com.android.systemui.util.mockito.mock
@@ -28,8 +30,13 @@
val Kosmos.keyguardBlueprintRepository by
Kosmos.Fixture {
KeyguardBlueprintRepository(
- configurationRepository = configurationRepository,
- blueprints = setOf(defaultBlueprint),
+ blueprints =
+ setOf(
+ defaultBlueprint,
+ splitShadeBlueprint,
+ weatherClockBlueprint,
+ splitShadeWeatherClockBlueprint,
+ ),
handler = fakeExecutorHandler,
assert = mock<ThreadAssert>(),
)
@@ -42,3 +49,27 @@
override val sections: List<KeyguardSection>
get() = listOf()
}
+
+private val weatherClockBlueprint =
+ object : KeyguardBlueprint {
+ override val id: String
+ get() = WEATHER_CLOCK_BLUEPRINT_ID
+ override val sections: List<KeyguardSection>
+ get() = listOf()
+ }
+
+private val splitShadeWeatherClockBlueprint =
+ object : KeyguardBlueprint {
+ override val id: String
+ get() = SPLIT_SHADE_WEATHER_CLOCK_BLUEPRINT_ID
+ override val sections: List<KeyguardSection>
+ get() = listOf()
+ }
+
+private val splitShadeBlueprint =
+ object : KeyguardBlueprint {
+ override val id: String
+ get() = SplitShadeKeyguardBlueprint.Companion.ID
+ override val sections: List<KeyguardSection>
+ get() = listOf()
+ }
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 5dd5073..a45b269 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 @@
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/domain/interactor/KeyguardBlueprintInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorKosmos.kt
index 8b0bba1..87d6c17 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorKosmos.kt
@@ -17,6 +17,8 @@
package com.android.systemui.keyguard.domain.interactor
import android.content.applicationContext
+import com.android.systemui.biometrics.domain.interactor.fingerprintPropertyInteractor
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.keyguard.data.repository.keyguardBlueprintRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
@@ -30,5 +32,7 @@
context = applicationContext,
splitShadeStateController = splitShadeStateController,
clockInteractor = keyguardClockInteractor,
+ configurationInteractor = configurationInteractor,
+ fingerprintPropertyInteractor = fingerprintPropertyInteractor,
)
}
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 00741eb..298c70d 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 @@
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 5f70a2f..450dcc2 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 @@
@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 23d657d..1ce2610 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/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/ForegroundServicesRepositoryKosmos.kt
similarity index 61%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/ForegroundServicesRepositoryKosmos.kt
index a025846..8f81b5e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/ForegroundServicesRepositoryKosmos.kt
@@ -14,17 +14,15 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.notification.stack.ui.viewmodel
+package com.android.systemui.qs.footer
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.scene.domain.interactor.PanelExpansionInteractor
-import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.shade.data.repository.shadeRepository
+import com.android.systemui.qs.fgsManagerController
+import com.android.systemui.qs.footer.data.repository.ForegroundServicesRepositoryImpl
-val Kosmos.panelExpansionInteractor by Fixture {
- PanelExpansionInteractor(
- sceneInteractor = sceneInteractor,
- shadeRepository = shadeRepository,
+val Kosmos.foregroundServicesRepository by Fixture {
+ ForegroundServicesRepositoryImpl(
+ fgsManagerController = fgsManagerController,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/security/data/repository/SecurityRepositoryKosmos.kt
similarity index 61%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/security/data/repository/SecurityRepositoryKosmos.kt
index a025846..6ac5bcb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/security/data/repository/SecurityRepositoryKosmos.kt
@@ -14,17 +14,16 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.notification.stack.ui.viewmodel
+package com.android.systemui.security.data.repository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.scene.domain.interactor.PanelExpansionInteractor
-import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.shade.data.repository.shadeRepository
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.statusbar.policy.securityController
-val Kosmos.panelExpansionInteractor by Fixture {
- PanelExpansionInteractor(
- sceneInteractor = sceneInteractor,
- shadeRepository = shadeRepository,
+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 4aab822..6b604e1 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
@@ -23,6 +23,7 @@
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 +60,9 @@
override val legacyLockscreenShadeTracking = MutableStateFlow(false)
+ private val _isSplitShade = MutableStateFlow(false)
+ override val isSplitShade: StateFlow<Boolean> = _isSplitShade.asStateFlow()
+
@Deprecated("Use ShadeInteractor instead")
override fun setLegacyIsQsExpanded(legacyIsQsExpanded: Boolean) {
_legacyIsQsExpanded.value = legacyIsQsExpanded
@@ -131,6 +135,10 @@
override fun setLegacyShadeExpansion(expandedFraction: Float) {
_legacyShadeExpansion.value = expandedFraction
}
+
+ override fun setSplitShade(isSplitShade: Boolean) {
+ _isSplitShade.value = isSplitShade
+ }
}
@Module
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorKosmos.kt
similarity index 71%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorKosmos.kt
index a025846..2a4dd3a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorKosmos.kt
@@ -14,17 +14,15 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.notification.stack.ui.viewmodel
+package com.android.systemui.shade.domain.interactor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.scene.domain.interactor.PanelExpansionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.shade.data.repository.shadeRepository
-val Kosmos.panelExpansionInteractor by Fixture {
- PanelExpansionInteractor(
+val Kosmos.panelExpansionInteractor by Fixture { panelExpansionInteractorImpl }
+val Kosmos.panelExpansionInteractorImpl by Fixture {
+ PanelExpansionInteractorImpl(
sceneInteractor = sceneInteractor,
- shadeRepository = shadeRepository,
)
}
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 2bd76be..07e2d6b 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 @@
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 0000000..b99fdb9
--- /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 c013664..de0cc65 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 @@
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 0000000..67a5cc9
--- /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
similarity index 94%
rename from packages/SystemUI/tests/src/com/android/systemui/user/data/repository/FakeUserSwitcherRepository.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserSwitcherRepository.kt
index 758fe93a..90fb60b 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/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/UserSwitcherRepositoryKosmos.kt
similarity index 60%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/UserSwitcherRepositoryKosmos.kt
index a025846..1519f30 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/PanelExpansionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/UserSwitcherRepositoryKosmos.kt
@@ -14,17 +14,9 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.notification.stack.ui.viewmodel
+package com.android.systemui.user.data.repository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.scene.domain.interactor.PanelExpansionInteractor
-import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.shade.data.repository.shadeRepository
-val Kosmos.panelExpansionInteractor by Fixture {
- PanelExpansionInteractor(
- sceneInteractor = sceneInteractor,
- shadeRepository = shadeRepository,
- )
-}
+val Kosmos.userSwitcherRepository by Fixture { FakeUserSwitcherRepository() }
diff --git a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
index e0fe88a..10e6ed4 100644
--- a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
+++ b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
@@ -1566,6 +1566,10 @@
private String mCameraId = null;
private IBinder mToken;
+ OutputSurfaceImplStub mOutputPreviewSurfaceImpl;
+ OutputSurfaceImplStub mOutputImageCaptureSurfaceImpl;
+ OutputSurfaceImplStub mOutputPostviewSurfaceImpl;
+
public SessionProcessorImplStub(SessionProcessorImpl sessionProcessor) {
mSessionProcessor = sessionProcessor;
}
@@ -1574,21 +1578,18 @@
public CameraSessionConfig initSession(IBinder token, String cameraId,
Map<String, CameraMetadataNative> charsMapNative, OutputSurface previewSurface,
OutputSurface imageCaptureSurface, OutputSurface postviewSurface) {
- OutputSurfaceImplStub outputPreviewSurfaceImpl =
- new OutputSurfaceImplStub(previewSurface);
- OutputSurfaceImplStub outputImageCaptureSurfaceImpl =
- new OutputSurfaceImplStub(imageCaptureSurface);
- OutputSurfaceImplStub outputPostviewSurfaceImpl =
- new OutputSurfaceImplStub(postviewSurface);
+ mOutputPreviewSurfaceImpl = new OutputSurfaceImplStub(previewSurface);
+ mOutputImageCaptureSurfaceImpl = new OutputSurfaceImplStub(imageCaptureSurface);
+ mOutputPostviewSurfaceImpl = new OutputSurfaceImplStub(postviewSurface);
Camera2SessionConfigImpl sessionConfig;
if (LATENCY_IMPROVEMENTS_SUPPORTED) {
OutputSurfaceConfigurationImplStub outputSurfaceConfigs =
- new OutputSurfaceConfigurationImplStub(outputPreviewSurfaceImpl,
+ new OutputSurfaceConfigurationImplStub(mOutputPreviewSurfaceImpl,
// Image Analysis Output is currently only supported in CameraX
- outputImageCaptureSurfaceImpl, null /*imageAnalysisSurfaceConfig*/,
- outputPostviewSurfaceImpl);
+ mOutputImageCaptureSurfaceImpl, null /*imageAnalysisSurfaceConfig*/,
+ mOutputPostviewSurfaceImpl);
sessionConfig = mSessionProcessor.initSession(cameraId,
getCharacteristicsMap(charsMapNative),
@@ -1596,8 +1597,8 @@
} else {
sessionConfig = mSessionProcessor.initSession(cameraId,
getCharacteristicsMap(charsMapNative),
- getApplicationContext(), outputPreviewSurfaceImpl,
- outputImageCaptureSurfaceImpl, null /*imageAnalysisSurfaceConfig*/);
+ getApplicationContext(), mOutputPreviewSurfaceImpl,
+ mOutputImageCaptureSurfaceImpl, null /*imageAnalysisSurfaceConfig*/);
}
List<Camera2OutputConfigImpl> outputConfigs = sessionConfig.getOutputConfigs();
@@ -1632,6 +1633,18 @@
public void deInitSession(IBinder token) {
CameraExtensionsProxyService.unregisterDeathRecipient(mToken, this);
mSessionProcessor.deInitSession();
+
+ if (Flags.surfaceLeakFix()) {
+ if (mOutputImageCaptureSurfaceImpl.mSurface != null) {
+ mOutputImageCaptureSurfaceImpl.mSurface.release();
+ }
+ if (mOutputPreviewSurfaceImpl.mSurface != null) {
+ mOutputPreviewSurfaceImpl.mSurface.release();
+ }
+ if (mOutputPostviewSurfaceImpl.mSurface != null) {
+ mOutputPostviewSurfaceImpl.mSurface.release();
+ }
+ }
}
@Override
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index cbb66dc..3cbfd42 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -40,6 +40,7 @@
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
+import static com.android.internal.accessibility.common.ShortcutConstants.USER_SHORTCUT_TYPES;
import static com.android.internal.accessibility.util.AccessibilityStatsLogUtils.logAccessibilityShortcutActivated;
import static com.android.internal.util.FunctionalUtils.ignoreRemoteException;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
@@ -111,6 +112,7 @@
import android.safetycenter.SafetyCenterManager;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IntArray;
import android.util.Log;
@@ -145,9 +147,13 @@
import com.android.internal.accessibility.AccessibilityShortcutController;
import com.android.internal.accessibility.AccessibilityShortcutController.FrameworkFeatureInfo;
import com.android.internal.accessibility.AccessibilityShortcutController.LaunchableFrameworkFeatureInfo;
+import com.android.internal.accessibility.common.ShortcutConstants;
+import com.android.internal.accessibility.common.ShortcutConstants.FloatingMenuSize;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity;
import com.android.internal.accessibility.dialog.AccessibilityShortcutChooserActivity;
import com.android.internal.accessibility.util.AccessibilityUtils;
+import com.android.internal.accessibility.util.ShortcutUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
@@ -168,6 +174,7 @@
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.pm.UserManagerInternal;
import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.utils.Slogf;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerInternal;
@@ -191,6 +198,7 @@
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
+import java.util.stream.Collectors;
/**
* This class is instantiated by the system as a system level service and can be
@@ -707,16 +715,6 @@
}
}
- 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) {
@@ -834,22 +832,16 @@
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);
}
}
@@ -867,10 +859,8 @@
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;
@@ -885,12 +875,8 @@
// 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);
}
@@ -985,34 +971,6 @@
// 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);
@@ -1986,10 +1944,8 @@
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;
@@ -2014,12 +1970,8 @@
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
@@ -2334,6 +2286,7 @@
if (!parsedAccessibilityServiceInfos.equals(userState.mInstalledServices)) {
userState.mInstalledServices.clear();
userState.mInstalledServices.addAll(parsedAccessibilityServiceInfos);
+ userState.updateTileServiceMapForAccessibilityServiceLocked();
return true;
}
return false;
@@ -2359,6 +2312,7 @@
if (!parsedAccessibilityShortcutInfos.equals(userState.mInstalledShortcuts)) {
userState.mInstalledShortcuts.clear();
userState.mInstalledShortcuts.addAll(parsedAccessibilityShortcutInfos);
+ userState.updateTileServiceMapForAccessibilityActivityLocked();
return true;
}
return false;
@@ -2621,6 +2575,12 @@
private <T> void persistColonDelimitedSetToSettingLocked(String settingName, int userId,
Set<T> set, Function<T, String> toString) {
+ persistColonDelimitedSetToSettingLocked(settingName, userId, set,
+ toString, /* defaultEmptyString= */ null);
+ }
+
+ private <T> void persistColonDelimitedSetToSettingLocked(String settingName, int userId,
+ Set<T> set, Function<T, String> toString, String defaultEmptyString) {
final StringBuilder builder = new StringBuilder();
for (T item : set) {
final String str = (item != null ? toString.apply(item) : null);
@@ -2636,7 +2596,18 @@
try {
final String settingValue = builder.toString();
Settings.Secure.putStringForUser(mContext.getContentResolver(),
- settingName, TextUtils.isEmpty(settingValue) ? null : settingValue, userId);
+ settingName,
+ TextUtils.isEmpty(settingValue) ? defaultEmptyString : settingValue, userId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ private void persistIntToSetting(int userId, String settingName, int settingValue) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ Settings.Secure.putIntForUser(
+ mContext.getContentResolver(), settingName, settingValue, userId);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -3005,6 +2976,7 @@
scheduleUpdateClientsIfNeededLocked(userState, forceUpdate);
updateAccessibilityShortcutKeyTargetsLocked(userState);
updateAccessibilityButtonTargetsLocked(userState);
+ updateAccessibilityQsTargetsLocked(userState);
// Update the capabilities before the mode because we will check the current mode is
// invalid or not..
updateMagnificationCapabilitiesSettingsChangeLocked(userState);
@@ -3107,15 +3079,6 @@
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,
@@ -3132,6 +3095,7 @@
somethingChanged |= readMagnificationEnabledSettingsLocked(userState);
somethingChanged |= readAutoclickEnabledSettingLocked(userState);
somethingChanged |= readAccessibilityShortcutKeySettingLocked(userState);
+ somethingChanged |= readAccessibilityQsTargetsLocked(userState);
somethingChanged |= readAccessibilityButtonTargetsLocked(userState);
somethingChanged |= readAccessibilityButtonTargetComponentLocked(userState);
somethingChanged |= readUserRecommendedUiTimeoutSettingsLocked(userState);
@@ -3305,6 +3269,21 @@
return true;
}
+ private boolean readAccessibilityQsTargetsLocked(AccessibilityUserState userState) {
+ final Set<String> targetsFromSetting = new ArraySet<>();
+ readColonDelimitedSettingToSet(Settings.Secure.ACCESSIBILITY_QS_TARGETS,
+ userState.mUserId, str -> str, targetsFromSetting);
+
+ final Set<String> currentTargets =
+ userState.getShortcutTargetsLocked(UserShortcutType.QUICK_SETTINGS);
+ if (targetsFromSetting.equals(currentTargets)) {
+ return false;
+ }
+ userState.updateA11yQsTargetLocked(targetsFromSetting);
+ scheduleNotifyClientsOfServicesStateChangeLocked(userState);
+ return true;
+ }
+
private boolean readAccessibilityButtonTargetsLocked(AccessibilityUserState userState) {
final Set<String> targetsFromSetting = new ArraySet<>();
readColonDelimitedSettingToSet(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
@@ -3636,6 +3615,8 @@
final Set<String> shortcutKeyTargets =
userState.getShortcutTargetsLocked(ACCESSIBILITY_SHORTCUT_KEY);
+ final Set<String> qsShortcutTargets =
+ userState.getShortcutTargetsLocked(UserShortcutType.QUICK_SETTINGS);
userState.mEnabledServices.forEach(componentName -> {
if (packageName != null && componentName != null
&& !packageName.equals(componentName.getPackageName())) {
@@ -3657,7 +3638,8 @@
return;
}
if (doesShortcutTargetsStringContain(buttonTargets, serviceName)
- || doesShortcutTargetsStringContain(shortcutKeyTargets, serviceName)) {
+ || doesShortcutTargetsStringContain(shortcutKeyTargets, serviceName)
+ || doesShortcutTargetsStringContain(qsShortcutTargets, serviceName)) {
return;
}
// For enabled a11y services targeting sdk version > Q and requesting a11y button should
@@ -3678,6 +3660,33 @@
}
/**
+ * Update the Settings.Secure.ACCESSIBILITY_QS_TARGETS so that it only contains valid content,
+ * and a side loaded service can't spoof the package name of the default service.
+ */
+ private void updateAccessibilityQsTargetsLocked(AccessibilityUserState userState) {
+ final Set<String> targets =
+ userState.getShortcutTargetsLocked(UserShortcutType.QUICK_SETTINGS);
+ final int lastSize = targets.size();
+ if (lastSize == 0) {
+ return;
+ }
+
+ // Removes the targets that are no longer installed on the device.
+ boolean somethingChanged = targets.removeIf(
+ name -> !userState.isShortcutTargetInstalledLocked(name));
+ if (!somethingChanged) {
+ return;
+ }
+ userState.updateA11yQsTargetLocked(targets);
+
+ // Update setting key with new value.
+ persistColonDelimitedSetToSettingLocked(
+ Settings.Secure.ACCESSIBILITY_QS_TARGETS,
+ userState.mUserId, targets, str -> str);
+ scheduleNotifyClientsOfServicesStateChangeLocked(userState);
+ }
+
+ /**
* Remove the shortcut target for the unbound service which is requesting accessibility button
* and targeting sdk > Q from the accessibility button and shortcut.
*
@@ -3691,19 +3700,42 @@
.targetSdkVersion <= Build.VERSION_CODES.Q) {
return;
}
+
+ final List<Pair<Integer, String>> shortcutTypeAndShortcutSetting = List.of(
+ new Pair<>(ACCESSIBILITY_SHORTCUT_KEY,
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE),
+ new Pair<>(ACCESSIBILITY_BUTTON,
+ Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS),
+ new Pair<>(UserShortcutType.QUICK_SETTINGS,
+ Settings.Secure.ACCESSIBILITY_QS_TARGETS)
+ );
+
final ComponentName serviceName = service.getComponentName();
- if (userState.removeShortcutTargetLocked(ACCESSIBILITY_SHORTCUT_KEY, serviceName)) {
- final Set<String> currentTargets = userState.getShortcutTargetsLocked(
- ACCESSIBILITY_SHORTCUT_KEY);
- persistColonDelimitedSetToSettingLocked(
- Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
- userState.mUserId, currentTargets, str -> str);
- }
- if (userState.removeShortcutTargetLocked(ACCESSIBILITY_BUTTON, serviceName)) {
- final Set<String> currentTargets = userState.getShortcutTargetsLocked(
- ACCESSIBILITY_BUTTON);
- persistColonDelimitedSetToSettingLocked(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
- userState.mUserId, currentTargets, str -> str);
+ for (Pair<Integer, String> shortcutTypePair : shortcutTypeAndShortcutSetting) {
+ int shortcutType = shortcutTypePair.first;
+ String shortcutSettingName = shortcutTypePair.second;
+ if (userState.removeShortcutTargetLocked(shortcutType, serviceName)) {
+ final Set<String> currentTargets = userState.getShortcutTargetsLocked(shortcutType);
+ persistColonDelimitedSetToSettingLocked(
+ shortcutSettingName,
+ userState.mUserId, currentTargets, str -> str);
+
+ if (shortcutType != UserShortcutType.QUICK_SETTINGS) {
+ continue;
+ }
+
+ ComponentName tileService =
+ userState.getA11yFeatureToTileService().getOrDefault(serviceName, null);
+
+ final StatusBarManagerInternal statusBarManagerInternal =
+ LocalServices.getService(StatusBarManagerInternal.class);
+ // In case it's not initialized yet
+ if (statusBarManagerInternal == null || tileService == null) {
+ continue;
+ }
+ mMainHandler.sendMessage(obtainMessage(StatusBarManagerInternal::removeQsTile,
+ statusBarManagerInternal, tileService));
+ }
}
}
@@ -3967,6 +3999,262 @@
}
}
+ /**
+ * Turns on or off a shortcut type of the accessibility features. The {@code shortcutTypes} is a
+ * flag that contains values defined in the
+ * {@link ShortcutConstants.USER_SHORTCUT_TYPES}.
+ *
+ * @hide
+ */
+ @Override
+ public void enableShortcutsForTargets(
+ boolean enable, @UserShortcutType int shortcutTypes,
+ @NonNull List<String> shortcutTargets, @UserIdInt int userId) {
+ mContext.enforceCallingPermission(
+ Manifest.permission.MANAGE_ACCESSIBILITY, "enableShortcutsForTargets");
+ for (int shortcutType : USER_SHORTCUT_TYPES) {
+ if ((shortcutTypes & shortcutType) == shortcutType) {
+ enableShortcutForTargets(enable, shortcutType, shortcutTargets, userId);
+ }
+ }
+ }
+
+ private void enableShortcutForTargets(
+ boolean enable, @UserShortcutType int shortcutType,
+ @NonNull List<String> shortcutTargets, @UserIdInt int userId) {
+ final String shortcutTypeSettingKey = ShortcutUtils.convertToKey(shortcutType);
+ if (shortcutType == UserShortcutType.TRIPLETAP
+ || shortcutType == UserShortcutType.TWOFINGER_DOUBLETAP) {
+ for (String target : shortcutTargets) {
+ if (MAGNIFICATION_CONTROLLER_NAME.equals(target)) {
+ persistIntToSetting(
+ userId,
+ shortcutTypeSettingKey,
+ enable ? AccessibilityUtils.State.ON : AccessibilityUtils.State.OFF);
+ } else {
+ Slog.w(LOG_TAG,
+ "Triple tap or two-fingers double-tap is not supported for " + target);
+ }
+ }
+ return;
+ }
+ Set<String> validNewTargets;
+ Set<String> currentTargets;
+
+ Map<ComponentName, ComponentName> featureToTileMap =
+ getA11yFeatureToTileMapInternal(userId);
+ synchronized (mLock) {
+ AccessibilityUserState userState = getUserStateLocked(userId);
+ currentTargets =
+ ShortcutUtils.getShortcutTargetsFromSettings(mContext, shortcutType, userId);
+
+ Set<String> newTargets = new ArraySet<>(currentTargets);
+ if (enable) {
+ newTargets.addAll(shortcutTargets);
+ } else {
+ newTargets.removeAll(shortcutTargets);
+ }
+ validNewTargets = newTargets;
+
+ // filter out targets that doesn't have qs shortcut
+ if (shortcutType == UserShortcutType.QUICK_SETTINGS) {
+ validNewTargets = newTargets.stream().filter(target -> {
+ ComponentName targetComponent = ComponentName.unflattenFromString(target);
+ return featureToTileMap.containsKey(targetComponent);
+ }).collect(Collectors.toUnmodifiableSet());
+ }
+
+ if (currentTargets.equals(validNewTargets)) {
+ return;
+ }
+ persistColonDelimitedSetToSettingLocked(
+ shortcutTypeSettingKey,
+ userId,
+ validNewTargets,
+ str -> str,
+ /* defaultEmptyString= */ ""
+ );
+
+ if (shortcutType == UserShortcutType.QUICK_SETTINGS) {
+ userState.updateA11yQsTargetLocked(validNewTargets);
+ scheduleNotifyClientsOfServicesStateChangeLocked(userState);
+ onUserStateChangedLocked(userState);
+ }
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
+ mContext, new ArraySet<>(shortcutTargets), userId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+
+ // Add or Remove tile in QS Panel
+ if (shortcutType == UserShortcutType.QUICK_SETTINGS) {
+ mMainHandler.sendMessage(obtainMessage(
+ AccessibilityManagerService::updateA11yTileServicesInQuickSettingsPanel,
+ this, validNewTargets, currentTargets, userId));
+ }
+
+ if (!enable) {
+ return;
+ }
+ if (shortcutType == UserShortcutType.HARDWARE) {
+ skipVolumeShortcutDialogTimeoutRestriction(userId);
+ } else if (shortcutType == UserShortcutType.SOFTWARE) {
+ // Update the A11y FAB size to large when the Magnification shortcut is
+ // enabled and the user hasn't changed the floating button size
+ if (shortcutTargets.contains(MAGNIFICATION_CONTROLLER_NAME)
+ && Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE,
+ FloatingMenuSize.UNKNOWN, userId) == FloatingMenuSize.UNKNOWN) {
+ persistIntToSetting(
+ userId,
+ Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE,
+ FloatingMenuSize.LARGE);
+ }
+ }
+ }
+
+ /**
+ * Add or remove the TileServices of the a11y features in the Quick Settings panel based on the
+ * changes in the new targets and current targets.
+ *
+ * <p>
+ * The framework tiles implemented in the SysUi are automatically added/removed via the
+ * SystemUI's AutoAddable framework. This method only handles updating the TileServices
+ * provided by AccessibilityService or Accessibility Activity.
+ * </p>
+ *
+ * @see com.android.systemui.qs.pipeline.domain.model.AutoAddable AutoAddable QS Tiles
+ */
+ private void updateA11yTileServicesInQuickSettingsPanel(
+ Set<String> newQsTargets,
+ Set<String> currentQsTargets, @UserIdInt int userId) {
+ // Call StatusBarManager to add/remove tiles
+ final StatusBarManagerInternal statusBarManagerInternal =
+ LocalServices.getService(StatusBarManagerInternal.class);
+ // In case it's not initialized yet
+ if (statusBarManagerInternal == null) {
+ return;
+ }
+
+ Map<ComponentName, ComponentName> a11yFeatureToTileMap =
+ getA11yFeatureToTileMapInternal(userId);
+ Set<String> targetWithNoTile = new ArraySet<>();
+
+ // Add TileServices to QS Panel that are added to the new targets
+ newQsTargets.stream()
+ .filter(target -> !currentQsTargets.contains(target))
+ .forEach(
+ target -> {
+ ComponentName targetComponent =
+ ComponentName.unflattenFromString(target);
+ if (targetComponent == null
+ || !a11yFeatureToTileMap.containsKey(targetComponent)) {
+ targetWithNoTile.add(target);
+ return;
+ }
+
+ if (ShortcutConstants.A11Y_FEATURE_TO_FRAMEWORK_TILE.containsKey(
+ targetComponent)) {
+ // a11y framework tile is handled by the SysUi autoaddable framework
+ return;
+ }
+ statusBarManagerInternal.addQsTileToFrontOrEnd(
+ a11yFeatureToTileMap.get(targetComponent), /* end= */ true);
+ }
+ );
+
+ // Remove TileServices from QS Panel that are no longer in the new targets.
+ currentQsTargets.stream()
+ .filter(target -> !newQsTargets.contains(target))
+ .forEach(
+ target -> {
+ ComponentName targetComponent =
+ ComponentName.unflattenFromString(target);
+ if (targetComponent == null
+ || !a11yFeatureToTileMap.containsKey(targetComponent)) {
+ targetWithNoTile.add(target);
+ return;
+ }
+
+ if (ShortcutConstants.A11Y_FEATURE_TO_FRAMEWORK_TILE.containsKey(
+ targetComponent)) {
+ // a11y framework tile is handled by the SysUi autoaddable framework
+ return;
+ }
+ statusBarManagerInternal.removeQsTile(
+ a11yFeatureToTileMap.get(targetComponent));
+ }
+ );
+
+ if (!targetWithNoTile.isEmpty()) {
+ throw new IllegalArgumentException(
+ "Unable to add/remove Tiles for a11y features: " + targetWithNoTile
+ + "as the Tiles aren't provided");
+ }
+ }
+
+ @Override
+ public Bundle getA11yFeatureToTileMap(@UserIdInt int userId) {
+ mContext.enforceCallingPermission(
+ Manifest.permission.MANAGE_ACCESSIBILITY, "getA11yFeatureToTileMap");
+
+ Bundle bundle = new Bundle();
+ Map<ComponentName, ComponentName> a11yFeatureToTile =
+ getA11yFeatureToTileMapInternal(userId);
+ for (Map.Entry<ComponentName, ComponentName> entry : a11yFeatureToTile.entrySet()) {
+ bundle.putParcelable(entry.getKey().flattenToString(), entry.getValue());
+ }
+ return bundle;
+ }
+
+
+
+ /**
+ * Returns accessibility feature's component and the provided tile map. This includes the
+ * TileService provided by the AccessibilityService or Accessibility Activity and the tile
+ * component provided by the framework's feature.
+ *
+ * @return a map of a feature's component name, and its provided tile's component name. The
+ * returned map's keys and values are not null. If a feature doesn't provide a tile, it won't
+ * have an entry in this map.
+ *
+ * @see ShortcutConstants.A11Y_FEATURE_TO_FRAMEWORK_TILE
+ */
+ @NonNull
+ private Map<ComponentName, ComponentName> getA11yFeatureToTileMapInternal(
+ @UserIdInt int userId) {
+ final Map<ComponentName, ComponentName> a11yFeatureToTileService;
+ Map<ComponentName, ComponentName> a11yFeatureToTile = new ArrayMap<>();
+ final int resolvedUserId;
+
+ synchronized (mLock) {
+ resolvedUserId = mSecurityPolicy
+ .resolveCallingUserIdEnforcingPermissionsLocked(userId);
+ AccessibilityUserState userState = getUserStateLocked(resolvedUserId);
+ a11yFeatureToTileService = userState.getA11yFeatureToTileService();
+ }
+ final boolean shouldFilterAppAccess = Binder.getCallingPid() != OWN_PROCESS_ID;
+ final int callingUid = Binder.getCallingUid();
+ final PackageManagerInternal pm = LocalServices.getService(
+ PackageManagerInternal.class);
+
+ for (Map.Entry<ComponentName, ComponentName> entry :
+ a11yFeatureToTileService.entrySet()) {
+ if (shouldFilterAppAccess
+ && pm.filterAppAccess(
+ entry.getKey().getPackageName(), callingUid, resolvedUserId)) {
+ continue;
+ }
+ a11yFeatureToTile.put(entry.getKey(), entry.getValue());
+ }
+
+ a11yFeatureToTile.putAll(ShortcutConstants.A11Y_FEATURE_TO_FRAMEWORK_TILE);
+ return a11yFeatureToTile;
+ }
+
@Override
public List<String> getAccessibilityShortcutTargets(@ShortcutType int shortcutType) {
if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_MANAGER)) {
@@ -5836,4 +6124,15 @@
}
}
}
+
+
+ /**
+ * Bypasses the timeout restriction if volume key shortcut assigned.
+ */
+ private void skipVolumeShortcutDialogTimeoutRestriction(int userId) {
+ persistIntToSetting(
+ userId,
+ Settings.Secure.SKIP_ACCESSIBILITY_SHORTCUT_DIALOG_TIMEOUT_RESTRICTION,
+ /* true */ 1);
+ }
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
index 68ee780..063eafe 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
@@ -38,10 +38,12 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.RemoteCallbackList;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseArray;
@@ -51,6 +53,7 @@
import com.android.internal.R;
import com.android.internal.accessibility.AccessibilityShortcutController;
+import com.android.internal.accessibility.common.ShortcutConstants;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -99,6 +102,7 @@
final ArraySet<String> mAccessibilityShortcutKeyTargets = new ArraySet<>();
final ArraySet<String> mAccessibilityButtonTargets = new ArraySet<>();
+ private final ArraySet<String> mAccessibilityQsTargets = new ArraySet<>();
private final ServiceInfoChangeListener mServiceInfoChangeListener;
@@ -146,6 +150,8 @@
private final int mFocusStrokeWidthDefaultValue;
// The default value of the focus color.
private final int mFocusColorDefaultValue;
+ private final Map<ComponentName, ComponentName> mA11yServiceToTileService = new ArrayMap<>();
+ private final Map<ComponentName, ComponentName> mA11yActivityToTileService = new ArrayMap<>();
private Context mContext;
@@ -560,6 +566,8 @@
pw.println("}");
pw.append(" button target:{").append(mTargetAssignedToAccessibilityButton);
pw.println("}");
+ pw.append(" qs shortcut targets:" + mAccessibilityQsTargets);
+ pw.println();
pw.append(" Bound services:{");
final int serviceCount = mBoundServices.size();
for (int j = 0; j < serviceCount; j++) {
@@ -762,6 +770,8 @@
return mAccessibilityShortcutKeyTargets;
} else if (shortcutType == ACCESSIBILITY_BUTTON) {
return mAccessibilityButtonTargets;
+ } else if (shortcutType == ShortcutConstants.UserShortcutType.QUICK_SETTINGS) {
+ return getA11yQsTargets();
}
return null;
}
@@ -808,7 +818,8 @@
*/
public boolean removeShortcutTargetLocked(@ShortcutType int shortcutType,
ComponentName target) {
- return getShortcutTargetsLocked(shortcutType).removeIf(name -> {
+ Set<String> targets = getShortcutTargetsLocked(shortcutType);
+ boolean result = targets.removeIf(name -> {
ComponentName componentName;
if (name == null
|| (componentName = ComponentName.unflattenFromString(name)) == null) {
@@ -816,6 +827,11 @@
}
return componentName.equals(target);
});
+ if (shortcutType == ShortcutConstants.UserShortcutType.QUICK_SETTINGS) {
+ updateA11yQsTargetLocked(targets);
+ }
+
+ return result;
}
/**
@@ -1034,4 +1050,60 @@
}
return false;
}
+
+ public void updateTileServiceMapForAccessibilityServiceLocked() {
+ mA11yServiceToTileService.clear();
+ mInstalledServices.forEach(
+ a11yServiceInfo -> {
+ String tileServiceName = a11yServiceInfo.getTileServiceName();
+ if (!TextUtils.isEmpty(tileServiceName)) {
+ ResolveInfo resolveInfo = a11yServiceInfo.getResolveInfo();
+ ComponentName a11yFeature = new ComponentName(
+ resolveInfo.serviceInfo.packageName,
+ resolveInfo.serviceInfo.name
+ );
+ ComponentName tileService = new ComponentName(
+ a11yFeature.getPackageName(),
+ tileServiceName
+ );
+ mA11yServiceToTileService.put(a11yFeature, tileService);
+ }
+ }
+ );
+ }
+
+ public void updateTileServiceMapForAccessibilityActivityLocked() {
+ mA11yActivityToTileService.clear();
+ mInstalledShortcuts.forEach(
+ a11yShortcutInfo -> {
+ String tileServiceName = a11yShortcutInfo.getTileServiceName();
+ if (!TextUtils.isEmpty(tileServiceName)) {
+ ComponentName a11yFeature = a11yShortcutInfo.getComponentName();
+ ComponentName tileService = new ComponentName(
+ a11yFeature.getPackageName(),
+ tileServiceName);
+ mA11yActivityToTileService.put(a11yFeature, tileService);
+ }
+ }
+ );
+ }
+
+ public void updateA11yQsTargetLocked(Set<String> targets) {
+ mAccessibilityQsTargets.clear();
+ mAccessibilityQsTargets.addAll(targets);
+ }
+
+ /**
+ * Returns a copy of the targets which has qs shortcut turned on
+ */
+ public ArraySet<String> getA11yQsTargets() {
+ return new ArraySet<>(mAccessibilityQsTargets);
+ }
+
+ public Map<ComponentName, ComponentName> getA11yFeatureToTileService() {
+ Map<ComponentName, ComponentName> featureToTileServiceMap = new ArrayMap<>();
+ featureToTileServiceMap.putAll(mA11yServiceToTileService);
+ featureToTileServiceMap.putAll(mA11yActivityToTileService);
+ return featureToTileServiceMap;
+ }
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 285e54c..e1291e5 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.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 @@
@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 13bc772..ca2a3dd 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 @@
} 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 b1672ed..8244d20 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.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.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 @@
runningAppsChangedCallback,
params,
DisplayManagerGlobal.getInstance(),
- Flags.virtualCamera()
+ isVirtualCameraEnabled()
? new VirtualCameraController(params.getDevicePolicy(POLICY_TYPE_CAMERA))
: null);
}
@@ -1535,4 +1538,13 @@
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 c5c2b0b..c7a8369 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.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.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 @@
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 @@
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 @@
@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 @@
}
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 258f53d..5298846 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_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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 5e36709..60bfc63 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 @@
// 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 @@
mInternal = new LocalService();
mPendingStartActivityUids = new PendingStartActivityUids();
mUseFifoUiScheduling = false;
- mEnableModernQueue = false;
mBroadcastQueue = injector.getBroadcastQueue(this);
mComponentAliasResolver = new ComponentAliasResolver(this);
}
@@ -2550,9 +2543,6 @@
? 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 @@
* 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 @@
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 @@
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 @@
+ " 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 @@
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 @@
}
@Override
- public boolean isModernQueueEnabled() {
- return mEnableModernQueue;
- }
-
- @Override
public void enforceBroadcastOptionsPermissions(Bundle options, int callingUid) {
enforceBroadcastOptionPermissionsInternal(options, callingUid);
}
@@ -18720,7 +18694,6 @@
Binder.restoreCallingIdentity(origId);
}
}
-
}
@Override
@@ -18730,12 +18703,8 @@
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 @@
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 1dc384d..3e633cc 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.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 @@
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 887915d..57080f8 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 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 @@
*/
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 @@
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 298eb79..e98e1ba 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 @@
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 @@
mActiveWasStopped = activeWasStopped;
}
+ public void setActiveFirstLaunch(boolean activeFirstLaunch) {
+ mActiveFirstLaunch = activeFirstLaunch;
+ }
+
public boolean getActiveViaColdStart() {
return mActiveViaColdStart;
}
@@ -634,6 +644,10 @@
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 569f9ec..5521381 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.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 @@
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 @@
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 @@
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 cb7898d..f76bf37 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_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 @@
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 @@
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 @@
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 @@
+ ": 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/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 982076d..91b64f8 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -80,6 +80,7 @@
sSecureSettingToTypeMap.put(Settings.Secure.MULTI_PRESS_TIMEOUT, int.class);
sSecureSettingToTypeMap.put(Settings.Secure.KEY_REPEAT_TIMEOUT_MS, int.class);
sSecureSettingToTypeMap.put(Settings.Secure.KEY_REPEAT_DELAY_MS, int.class);
+ sSecureSettingToTypeMap.put(Settings.Secure.STYLUS_POINTER_ICON_ENABLED, int.class);
// add other secure settings here...
sSystemSettingToTypeMap.put(Settings.System.TIME_12_24, String.class);
diff --git a/services/core/java/com/android/server/am/HostingRecord.java b/services/core/java/com/android/server/am/HostingRecord.java
index 30811a1..1a78a13 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 @@
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/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index a1fdd50..27d6c60 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_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 @@
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 7356588..9fa3a8b 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 @@
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 @@
@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 feab2c05..bac5132 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 13a1807..70d447f 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 @@
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 @@
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 @@
| 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}, /* 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 38051c1..177c345 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 @@
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.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 @@
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 @@
}
/** 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 @@
/**
* 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, currentState);
+ 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;
+ }
+
+ 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 @@
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 @@
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 @@
* 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 @@
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 @@
}
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 @@
}
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 @@
}
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 02c9bb3..97913de3 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.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 @@
}
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 f9aefd0..46478c1 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 @@
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 b865c1d9..8d07609 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.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 d92629f..df7301e 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 @@
@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 6c3fd83d..041ab3a 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 @@
}
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 e54f30f..146810f 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 @@
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 ad89444..ce7c224 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 @@
// 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 @@
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 @@
@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 @@
return mHdrConversionMode;
}
}
- return new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM);
+ return new HdrConversionMode(mDefaultHdrConversionMode);
}
HdrConversionMode getHdrConversionModeInternal() {
@@ -2473,6 +2479,14 @@
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 @@
*/
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 2e8de31..3452e0f 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 @@
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 @@
// 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 @@
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 @@
@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 @@
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 c6d66db..d997020 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 @@
}
@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 252ea4b..0ef23e9 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 @@
@Override
public void setSystemWideGrammaticalGender(int grammaticalGender, int userId) {
- checkCallerIsSystem();
+ isCallerAllowed();
GrammaticalInflectionService.this.setSystemWideGrammaticalGender(grammaticalGender,
userId);
}
@@ -154,7 +154,7 @@
@Override
@Nullable
public byte[] getBackupPayload(int userId) {
- checkCallerIsSystem();
+ isCallerAllowed();
return mBackupHelper.getBackupPayload(userId);
}
@@ -333,11 +333,13 @@
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/input/InputSettingsObserver.java b/services/core/java/com/android/server/input/InputSettingsObserver.java
index c02d524..a1341b7 100644
--- a/services/core/java/com/android/server/input/InputSettingsObserver.java
+++ b/services/core/java/com/android/server/input/InputSettingsObserver.java
@@ -258,6 +258,7 @@
}
private void updateStylusPointerIconEnabled() {
- mNative.setStylusPointerIconEnabled(InputSettings.isStylusPointerIconEnabled(mContext));
+ mNative.setStylusPointerIconEnabled(
+ InputSettings.isStylusPointerIconEnabled(mContext, true /* forceReloadSetting */));
}
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 19f0298..996477d 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -1247,6 +1247,14 @@
*/
private boolean mImePackageAppeared = false;
+ /**
+ * Remembers package names passed to {@link #onPackageDataCleared(String, int)}.
+ *
+ * <p>This field must be accessed only from callback methods in {@link PackageMonitor},
+ * which should be bound to {@link #getRegisteredHandler()}.</p>
+ */
+ private ArrayList<String> mDataClearedPackages = new ArrayList<>();
+
@GuardedBy("ImfLock.class")
void clearKnownImePackageNamesLocked() {
mKnownImePackageNames.clear();
@@ -1350,36 +1358,8 @@
@Override
public void onPackageDataCleared(String packageName, int uid) {
- final int userId = getChangingUserId();
- synchronized (ImfLock.class) {
- final boolean isCurrentUser = (userId == mSettings.getUserId());
- final AdditionalSubtypeMap additionalSubtypeMap =
- AdditionalSubtypeMapRepository.get(userId);
- final InputMethodSettings settings;
- if (isCurrentUser) {
- settings = mSettings;
- } else {
- settings = queryInputMethodServicesInternal(mContext, userId,
- additionalSubtypeMap, DirectBootAwareness.AUTO);
- }
-
- // Note that one package may implement multiple IMEs.
- final ArrayList<String> changedImes = new ArrayList<>();
- for (InputMethodInfo imi : settings.getMethodList()) {
- if (imi.getPackageName().equals(packageName)) {
- changedImes.add(imi.getId());
- }
- }
- final AdditionalSubtypeMap newMap =
- additionalSubtypeMap.cloneWithRemoveOrSelf(changedImes);
- if (newMap != additionalSubtypeMap) {
- AdditionalSubtypeMapRepository.putAndSave(userId, newMap,
- settings.getMethodMap());
- }
- if (!changedImes.isEmpty()) {
- mChangedPackages.add(packageName);
- }
- }
+ mChangedPackages.add(packageName);
+ mDataClearedPackages.add(packageName);
}
@Override
@@ -1391,6 +1371,7 @@
private void clearPackageChangeState() {
// No need to lock them because we access these fields only on getRegisteredHandler().
mChangedPackages.clear();
+ mDataClearedPackages.clear();
mImePackageAppeared = false;
}
@@ -1421,7 +1402,7 @@
synchronized (ImfLock.class) {
final int userId = getChangingUserId();
final boolean isCurrentUser = (userId == mSettings.getUserId());
- AdditionalSubtypeMap additionalSubtypeMap =
+ final AdditionalSubtypeMap additionalSubtypeMap =
AdditionalSubtypeMapRepository.get(userId);
final InputMethodSettings settings;
if (isCurrentUser) {
@@ -1434,6 +1415,8 @@
InputMethodInfo curIm = null;
String curInputMethodId = settings.getSelectedInputMethod();
final List<InputMethodInfo> methodList = settings.getMethodList();
+
+ final ArrayList<String> imesToClearAdditionalSubtypes = new ArrayList<>();
final int numImes = methodList.size();
for (int i = 0; i < numImes; i++) {
InputMethodInfo imi = methodList.get(i);
@@ -1441,6 +1424,9 @@
if (imiId.equals(curInputMethodId)) {
curIm = imi;
}
+ if (mDataClearedPackages.contains(imi.getPackageName())) {
+ imesToClearAdditionalSubtypes.add(imiId);
+ }
int change = isPackageDisappearing(imi.getPackageName());
if (change == PACKAGE_TEMPORARY_CHANGE || change == PACKAGE_PERMANENT_CHANGE) {
Slog.i(TAG, "Input method uninstalled, disabling: " + imi.getComponent());
@@ -1455,14 +1441,22 @@
} else if (change == PACKAGE_UPDATING) {
Slog.i(TAG, "Input method reinstalling, clearing additional subtypes: "
+ imi.getComponent());
- additionalSubtypeMap =
- additionalSubtypeMap.cloneWithRemoveOrSelf(imi.getId());
- AdditionalSubtypeMapRepository.putAndSave(userId,
- additionalSubtypeMap, settings.getMethodMap());
+ imesToClearAdditionalSubtypes.add(imiId);
}
}
- if (!isCurrentUser || !shouldRebuildInputMethodListLocked()) {
+ // Clear additional subtypes as a batch operation.
+ final AdditionalSubtypeMap newAdditionalSubtypeMap =
+ additionalSubtypeMap.cloneWithRemoveOrSelf(imesToClearAdditionalSubtypes);
+ final boolean additionalSubtypeChanged =
+ (newAdditionalSubtypeMap != additionalSubtypeMap);
+ if (additionalSubtypeChanged) {
+ AdditionalSubtypeMapRepository.putAndSave(userId, newAdditionalSubtypeMap,
+ settings.getMethodMap());
+ }
+
+ if (!isCurrentUser
+ || !(additionalSubtypeChanged || shouldRebuildInputMethodListLocked())) {
return;
}
diff --git a/services/core/java/com/android/server/location/contexthub/OWNERS b/services/core/java/com/android/server/location/contexthub/OWNERS
index 90c2330..c62e323 100644
--- a/services/core/java/com/android/server/location/contexthub/OWNERS
+++ b/services/core/java/com/android/server/location/contexthub/OWNERS
@@ -1,3 +1,3 @@
-arthuri@google.com
bduddie@google.com
+matthewsedam@google.com
stange@google.com
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 f60f55c..7acc3ef 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 @@
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 @@
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 @@
!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 @@
.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 @@
getFilteredAudioSampleRateHz(
inputMediaItemInfo.getAudioSampleRateHz()))
.writeInt(inputMediaItemInfo.getAudioChannelCount())
+ .writeLong(inputMediaItemInfo.getAudioSampleCount())
.writeInt(inputVideoSize.getWidth())
.writeInt(inputVideoSize.getHeight())
.writeInt(inputVideoResolution)
@@ -456,6 +512,28 @@
.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 @@
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/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 18b495b..97ce77c 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -340,6 +340,8 @@
static final String TAG = NetworkPolicyLogger.TAG;
private static final boolean LOGD = NetworkPolicyLogger.LOGD;
private static final boolean LOGV = NetworkPolicyLogger.LOGV;
+ // TODO: b/304347838 - Remove once the feature is in staging.
+ private static final boolean ALWAYS_RESTRICT_BACKGROUND_NETWORK = false;
/**
* No opportunistic quota could be calculated from user data plan or data settings.
@@ -1068,7 +1070,8 @@
}
// The flag is boot-stable.
- mBackgroundNetworkRestricted = Flags.networkBlockedForTopSleepingAndAbove();
+ mBackgroundNetworkRestricted = ALWAYS_RESTRICT_BACKGROUND_NETWORK
+ && Flags.networkBlockedForTopSleepingAndAbove();
if (mBackgroundNetworkRestricted) {
// Firewall rules and UidBlockedState will get updated in
// updateRulesForGlobalChangeAL below.
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index b98424c..e7455db 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 @@
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 9af2b3f..278deb8 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 @@
+ 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 29de26e..ec98fff 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 @@
}
/**
+ * 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 @@
}
// 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/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 59d6219..e35a169 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2710,7 +2710,8 @@
} catch (java.io.IOException e) {
mReadMessages.append("Error reading: " + e.toString());
- PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
+ PackageManagerService.reportSettingsProblem(Log.ERROR,
+ "Error reading stopped packages: " + e);
Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
e);
diff --git a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
index 1b220a0..453c6ef 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.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.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 @@
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 @@
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 @@
}
}
- 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 @@
@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 @@
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 @@
}
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 @@
}
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 @@
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 @@
}
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 @@
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 652cf18..fde49d2 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 @@
}
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 @@
}
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 a172de0..b50e2bf 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 @@
* 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 78f501a..59a56de 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 @@
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 @@
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 @@
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 7ba953d..0069cdd 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_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_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.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 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 @@
// 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 @@
// 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 @@
}
/**
+ * 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 @@
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 @@
: 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 e283f3e..060f1c8 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 @@
}
/**
- * 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 826e332..2fc6b5f 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.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.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 @@
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 @@
// 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 @@
+ "(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 @@
}
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 @@
// 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 c79a8b6..25885ed 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 SyncGroup {
final int mSyncId;
+ final String mSyncName;
int mSyncMethod = METHOD_BLAST;
final TransactionReadyListener mListener;
final Runnable mOnTimeout;
@@ -138,6 +139,7 @@
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 @@
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 @@
// 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 e155126..e3ac35c 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 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 @@
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 @@
|| (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 7052982..877378c 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 @@
// 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 d3acd71..282ecc7 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
(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,60 +3575,62 @@
}
/**
- * 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);
- }
- }
- mWmService.mLatencyTracker.onActionStart(ACTION_ROTATE_SCREEN);
- controller.mTransitionMetricsReporter.associate(t.getToken(),
- startTime -> mWmService.mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN));
- startAsyncRotation(false /* shouldDebounce */);
+ setSeamlessTransitionForFixedRotation(transition);
}
- t.setKnownConfigChanges(this, changes);
+ } 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);
+ }
+
private void setSeamlessTransitionForFixedRotation(Transition t) {
t.setSeamlessRotation(this);
// Before the start transaction is applied, the non-app windows need to keep in previous
@@ -5722,14 +5748,8 @@
*/
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 @@
|| 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 @@
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 57b9c63..e789fec 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 @@
*/
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 @@
*/
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 @@
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 @@
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 @@
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 d376613..384b91a 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 @@
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 9fee343..21326be 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.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 @@
*/
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 @@
*/
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 @@
*/
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 @@
|| 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 @@
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 6d11804..b8bb258 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 @@
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 2b841fd..4c797f8 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 @@
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 @@
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/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index a75d3b6..445a5c8 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2327,7 +2327,7 @@
}
/**
- * Finish the topmost activities in all root tasks that belong to the crashed app.
+ * Finish the topmost activities in all leaf tasks that belong to the crashed app.
*
* @param app The app that crashed.
* @param reason Reason to perform this action.
@@ -2338,14 +2338,14 @@
Task finishTopCrashedActivities(WindowProcessController app, String reason) {
Task focusedRootTask = getTopDisplayFocusedRootTask();
final Task[] finishedTask = new Task[1];
- forAllRootTasks(rootTask -> {
+ forAllLeafTasks(leafTask -> {
final boolean recordTopOrVisible = finishedTask[0] == null
- && (focusedRootTask == rootTask || rootTask.isVisibleRequested());
- final Task t = rootTask.finishTopCrashedActivityLocked(app, reason);
+ && (focusedRootTask == leafTask.getRootTask() || leafTask.isVisibleRequested());
+ final Task t = leafTask.finishTopCrashedActivityLocked(app, reason);
if (recordTopOrVisible) {
finishedTask[0] = t;
}
- });
+ }, true);
return finishedTask[0];
}
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 597e901..c919250 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 @@
// 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 @@
* @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 @@
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 7edc3a2..6d8b030 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 @@
}
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 @@
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 @@
}
/**
+ * 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 @@
} 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 @@
} 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 503f925..ac03a1b 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_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 @@
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 @@
* 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 @@
}
} 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 @@
* @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 fd0289e..f2af852 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 @@
// 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 @@
}
/**
+ * 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 7b0d931..294733e 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 @@
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 a055db2..71ffabf 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 @@
/** 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 @@
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 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 a7eb444..a63e106 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 @@
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 ee16a37..6ac2774 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 @@
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 @@
@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 @@
&& (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 13e1ba78..4dca23b 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 @@
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 3607ddd..7a710dc 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -40,6 +40,7 @@
"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 @@
static_libs: [
"android.hardware.broadcastradio@common-utils-1x-lib",
"libaidlcommonsupport",
+ "libvirtualdevicebuildflags",
],
product_variables: {
diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
index 4403bce..95e7b19 100644
--- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
+++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
@@ -393,6 +393,7 @@
++pageoutVmaIndex;
break;
}
+ return true;
};
meminfo.ForEachVmaFromMaps(vmaCollectorCb, mapsBuffer);
ATRACE_END();
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 0000000..1e6a9db
--- /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 0936888..6464081 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -65,6 +65,7 @@
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 @@
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 86f4176..4a94732 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 a98d4e5..5bb216e 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 @@
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 @@
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 @@
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 bc264a4..95c4407 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 @@
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 @@
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 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 42e41d5..bc8643f 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 @@
// 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 @@
@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 @@
@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 @@
@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 @@
// 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 @@
}
}
- 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 @@
}
}
- 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 @@
@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 @@
/** 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 @@
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 @@
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 @@
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 @@
}
/**
- * 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 @@
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,
+ /** 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),
- activeStatePredicate);
+ return new DeviceStatePredicateWrapper(deviceState, activeStatePredicate);
}
- public static DeviceStateConfiguration createConfig(
- @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to =
- MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier,
- @NonNull String name,
- @NonNull Predicate<FoldableDeviceStateProvider> activeStatePredicate
- ) {
- return new DeviceStateConfiguration(new DeviceState(identifier, name, /* flags= */ 0),
- 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 @@
* 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 @@
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 @@
}
}
- 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 930f4a6..c9bbfee 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_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.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.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 @@
@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 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 @@
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 @@
@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 @@
@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 @@
@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 @@
@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 @@
@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 @@
@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 @@
@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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
@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 @@
@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 @@
@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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
@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 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 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 @@
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 @@
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 9d95c5b..2112dae 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -76,6 +76,7 @@
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 @@
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 d0913d2..58714a8 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.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 @@
private val writeLock = Any()
fun initialize() {
- writeHandler = WriteHandler(BackgroundThread.getHandler().looper)
+ writeHandler = WriteHandler(IoThread.getHandler().looper)
}
/**
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt
index c5c921d..7c75138 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt
@@ -477,9 +477,7 @@
if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT)) {
flags = flags or UPGRADE_EXEMPT
}
- // We ignore whether FLAG_PERMISSION_APPLY_RESTRICTION is set here because previously
- // platform may be relying on the old restorePermissionState() to get it correct later.
- if (!flags.hasAnyBit(MASK_EXEMPT)) {
+ if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION)) {
if (permission.isHardRestricted) {
flags = flags or RESTRICTION_REVOKED
}
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 bed6f92..2939192 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 @@
/* 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 079bc37..a2756ff 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.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 @@
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 95cfc2a..7f88b00 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -61,29 +61,38 @@
import android.graphics.drawable.Icon;
import android.hardware.display.DisplayManagerGlobal;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
+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;
import android.provider.Settings;
+import android.testing.AndroidTestingRunner;
import android.testing.TestableContext;
+import android.testing.TestableLooper;
import android.util.ArraySet;
import android.view.Display;
import android.view.DisplayAdjustments;
import android.view.DisplayInfo;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityWindowAttributes;
+import android.view.accessibility.IAccessibilityManager;
-import androidx.test.InstrumentationRegistry;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
import com.android.compatibility.common.util.TestUtils;
import com.android.internal.R;
+import com.android.internal.accessibility.common.ShortcutConstants;
+import com.android.internal.accessibility.common.ShortcutConstants.FloatingMenuSize;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
+import com.android.internal.accessibility.util.AccessibilityUtils;
+import com.android.internal.accessibility.util.ShortcutUtils;
import com.android.internal.compat.IPlatformCompat;
import com.android.server.LocalServices;
import com.android.server.accessibility.AccessibilityManagerService.AccessibilityDisplayListener;
@@ -91,31 +100,38 @@
import com.android.server.accessibility.magnification.MagnificationConnectionManager;
import com.android.server.accessibility.magnification.MagnificationController;
import com.android.server.accessibility.magnification.MagnificationProcessor;
-import com.android.server.accessibility.test.MessageCapturingHandler;
import com.android.server.pm.UserManagerInternal;
+import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerInternal;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.mockito.internal.util.reflection.FieldReader;
+import org.mockito.internal.util.reflection.FieldSetter;
import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
/**
* APCT tests for {@link AccessibilityManagerService}.
*/
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
public class AccessibilityManagerServiceTest {
@Rule
public final A11yTestableContext mTestableContext = new A11yTestableContext(
@@ -140,6 +156,12 @@
TEST_PENDING_INTENT);
private static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY + 1;
+ private static final String TARGET_MAGNIFICATION = MAGNIFICATION_CONTROLLER_NAME;
+ private static final ComponentName TARGET_ALWAYS_ON_A11Y_SERVICE =
+ new ComponentName("FakePackage", "AlwaysOnA11yService");
+ private static final String TARGET_ALWAYS_ON_A11Y_SERVICE_TILE_CLASS = "TileService";
+ private static final ComponentName TARGET_STANDARD_A11Y_SERVICE =
+ new ComponentName("FakePackage", "StandardA11yService");
static final ComponentName COMPONENT_NAME = new ComponentName(
"com.android.server.accessibility", "AccessibilityManagerServiceTest");
@@ -163,24 +185,33 @@
@Mock private MagnificationController mMockMagnificationController;
@Mock private FullScreenMagnificationController mMockFullScreenMagnificationController;
@Mock private ProxyManager mProxyManager;
+ @Mock private StatusBarManagerInternal mStatusBarManagerInternal;
@Captor private ArgumentCaptor<Intent> mIntentArgumentCaptor;
- private MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
+ private IAccessibilityManager mA11yManagerServiceOnDevice;
private AccessibilityServiceConnection mAccessibilityServiceConnection;
private AccessibilityInputFilter mInputFilter;
private AccessibilityManagerService mA11yms;
+ private TestableLooper mTestableLooper;
+ private Handler mHandler;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ mTestableLooper = TestableLooper.get(this);
+ mHandler = new Handler(mTestableLooper.getLooper());
+
LocalServices.removeServiceForTest(WindowManagerInternal.class);
LocalServices.removeServiceForTest(ActivityTaskManagerInternal.class);
LocalServices.removeServiceForTest(UserManagerInternal.class);
+ LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
LocalServices.addService(
WindowManagerInternal.class, mMockWindowManagerService);
LocalServices.addService(
ActivityTaskManagerInternal.class, mMockActivityTaskManagerInternal);
LocalServices.addService(
UserManagerInternal.class, mMockUserManagerInternal);
+ LocalServices.addService(
+ StatusBarManagerInternal.class, mStatusBarManagerInternal);
mInputFilter = Mockito.mock(FakeInputFilter.class);
when(mMockMagnificationController.getMagnificationConnectionManager()).thenReturn(
@@ -218,6 +249,19 @@
final AccessibilityUserState userState = new AccessibilityUserState(
mA11yms.getCurrentUserIdLocked(), mTestableContext, mA11yms);
mA11yms.mUserStates.put(mA11yms.getCurrentUserIdLocked(), userState);
+ AccessibilityManager am = mTestableContext.getSystemService(AccessibilityManager.class);
+ mA11yManagerServiceOnDevice = (IAccessibilityManager) new FieldReader(am,
+ AccessibilityManager.class.getDeclaredField("mService")).read();
+ FieldSetter.setField(am, AccessibilityManager.class.getDeclaredField("mService"), mA11yms);
+ }
+
+ @After
+ public void cleanUp() throws Exception {
+ mTestableLooper.processAllMessages();
+ AccessibilityManager am = mTestableContext.getSystemService(AccessibilityManager.class);
+ FieldSetter.setField(
+ am, AccessibilityManager.class.getDeclaredField("mService"),
+ mA11yManagerServiceOnDevice);
}
private void setupAccessibilityServiceConnection(int serviceInfoFlag) {
@@ -297,7 +341,8 @@
mA11yms.getCurrentUserIdLocked());
mA11yms.notifySystemActionsChangedLocked(userState);
- InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ mTestableLooper.processAllMessages();
+
verify(mMockServiceClient).onSystemActionsChanged();
}
@@ -415,7 +460,7 @@
);
mA11yms.onMagnificationTransitionEndedLocked(Display.DEFAULT_DISPLAY, true);
- mHandler.sendAllMessages();
+ mTestableLooper.processAllMessages();
ArgumentCaptor<Display> displayCaptor = ArgumentCaptor.forClass(Display.class);
verify(mInputFilter, timeout(100)).refreshMagnificationMode(displayCaptor.capture());
@@ -730,7 +775,7 @@
mA11yms.performAccessibilityShortcut(
ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
- mHandler.sendAllMessages();
+ mTestableLooper.processAllMessages();
assertStartActivityWithExpectedComponentName(mTestableContext.getMockContext(),
ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
@@ -805,26 +850,6 @@
}
@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();
@@ -842,7 +867,6 @@
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_SCAN_PACKAGES_WITHOUT_LOCK)
public void testSwitchUserScanPackages_scansWithoutHoldingLock() {
setupAccessibilityServiceConnection(0);
final AtomicReference<Set<Boolean>> lockState = collectLockStateWhilePackageScanning();
@@ -907,11 +931,14 @@
public void testIsAccessibilityServiceWarningRequired_notRequiredIfAllowlisted() {
mockManageAccessibilityGranted(mTestableContext);
final AccessibilityServiceInfo info_a = mockAccessibilityServiceInfo(
- new ComponentName("package_a", "class_a"), true);
+ new ComponentName("package_a", "class_a"),
+ /* isSystemApp= */ true, /* isAlwaysOnService= */ false);
final AccessibilityServiceInfo info_b = mockAccessibilityServiceInfo(
- new ComponentName("package_b", "class_b"), false);
+ new ComponentName("package_b", "class_b"),
+ /* isSystemApp= */ false, /* isAlwaysOnService= */ false);
final AccessibilityServiceInfo info_c = mockAccessibilityServiceInfo(
- new ComponentName("package_c", "class_c"), true);
+ new ComponentName("package_c", "class_c"),
+ /* isSystemApp= */ true, /* isAlwaysOnService= */ false);
mTestableContext.getOrCreateTestableResources().addOverride(
R.array.config_trustedAccessibilityServices,
new String[]{
@@ -926,14 +953,380 @@
assertThat(mA11yms.isAccessibilityServiceWarningRequired(info_c)).isFalse();
}
+ @Test
+ public void enableShortcutsForTargets_permissionNotGranted_throwsException() {
+ mTestableContext.getTestablePermissions().setPermission(
+ Manifest.permission.MANAGE_ACCESSIBILITY, PackageManager.PERMISSION_DENIED);
+
+ assertThrows(SecurityException.class,
+ () -> mA11yms.enableShortcutsForTargets(
+ /* enable= */true,
+ UserShortcutType.SOFTWARE,
+ List.of(TARGET_MAGNIFICATION),
+ mA11yms.getCurrentUserIdLocked()));
+ }
+
+ @Test
+ public void enableShortcutsForTargets_enableSoftwareShortcut_shortcutTurnedOn()
+ throws Exception {
+ mockManageAccessibilityGranted(mTestableContext);
+ setupShortcutTargetServices();
+ String target = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString();
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ true,
+ UserShortcutType.SOFTWARE,
+ List.of(target),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(ShortcutUtils.isComponentIdExistingInSettings(
+ mTestableContext, UserShortcutType.SOFTWARE, target
+ )).isTrue();
+ }
+
+ @Test
+ public void enableShortcutsForTargets_disableSoftwareShortcut_shortcutTurnedOff()
+ throws Exception {
+ String target = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString();
+ enableShortcutsForTargets_enableSoftwareShortcut_shortcutTurnedOn();
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ false,
+ UserShortcutType.SOFTWARE,
+ List.of(target),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(ShortcutUtils.isComponentIdExistingInSettings(
+ mTestableContext, UserShortcutType.SOFTWARE, target
+ )).isFalse();
+ }
+
+ @Test
+ public void enableShortcutsForTargets_enableSoftwareShortcutWithMagnification_menuSizeIncreased() {
+ mockManageAccessibilityGranted(mTestableContext);
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ true,
+ UserShortcutType.SOFTWARE,
+ List.of(MAGNIFICATION_CONTROLLER_NAME),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(
+ Settings.Secure.getInt(
+ mTestableContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE,
+ FloatingMenuSize.UNKNOWN))
+ .isEqualTo(FloatingMenuSize.LARGE);
+ }
+
+ @Test
+ public void enableShortcutsForTargets_enableSoftwareShortcutWithMagnification_userConfigureSmallMenuSize_menuSizeNotChanged() {
+ mockManageAccessibilityGranted(mTestableContext);
+ Settings.Secure.putInt(
+ mTestableContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE,
+ FloatingMenuSize.SMALL);
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ true,
+ UserShortcutType.SOFTWARE,
+ List.of(MAGNIFICATION_CONTROLLER_NAME),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(
+ Settings.Secure.getInt(
+ mTestableContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE,
+ FloatingMenuSize.UNKNOWN))
+ .isEqualTo(FloatingMenuSize.SMALL);
+ }
+
+ @Test
+ public void enableShortcutsForTargets_enableAlwaysOnServiceSoftwareShortcut_turnsOnAlwaysOnService()
+ throws Exception {
+ mockManageAccessibilityGranted(mTestableContext);
+ setupShortcutTargetServices();
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ true,
+ UserShortcutType.SOFTWARE,
+ List.of(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(
+ AccessibilityUtils.getEnabledServicesFromSettings(
+ mTestableContext,
+ mA11yms.getCurrentUserIdLocked())
+ ).contains(TARGET_ALWAYS_ON_A11Y_SERVICE);
+ }
+
+ @Test
+ public void enableShortcutsForTargets_disableAlwaysOnServiceSoftwareShortcut_turnsOffAlwaysOnService()
+ throws Exception {
+ enableShortcutsForTargets_enableAlwaysOnServiceSoftwareShortcut_turnsOnAlwaysOnService();
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ false,
+ UserShortcutType.SOFTWARE,
+ List.of(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(
+ AccessibilityUtils.getEnabledServicesFromSettings(
+ mTestableContext,
+ mA11yms.getCurrentUserIdLocked())
+ ).doesNotContain(TARGET_ALWAYS_ON_A11Y_SERVICE);
+ }
+
+ @Test
+ public void enableShortcutsForTargets_enableStandardServiceSoftwareShortcut_wontTurnOnService()
+ throws Exception {
+ mockManageAccessibilityGranted(mTestableContext);
+ setupShortcutTargetServices();
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ true,
+ UserShortcutType.SOFTWARE,
+ List.of(TARGET_STANDARD_A11Y_SERVICE.flattenToString()),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(
+ AccessibilityUtils.getEnabledServicesFromSettings(
+ mTestableContext,
+ mA11yms.getCurrentUserIdLocked())
+ ).doesNotContain(TARGET_STANDARD_A11Y_SERVICE);
+ }
+
+ @Test
+ public void enableShortcutsForTargets_disableStandardServiceSoftwareShortcutWithServiceOn_wontTurnOffService()
+ throws Exception {
+ enableShortcutsForTargets_enableStandardServiceSoftwareShortcut_wontTurnOnService();
+ AccessibilityUtils.setAccessibilityServiceState(
+ mTestableContext, TARGET_STANDARD_A11Y_SERVICE, /* enabled= */ true);
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ false,
+ UserShortcutType.SOFTWARE,
+ List.of(TARGET_STANDARD_A11Y_SERVICE.flattenToString()),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(
+ AccessibilityUtils.getEnabledServicesFromSettings(
+ mTestableContext,
+ mA11yms.getCurrentUserIdLocked())
+ ).contains(TARGET_STANDARD_A11Y_SERVICE);
+ }
+
+ @Test
+ public void enableShortcutsForTargets_enableTripleTapShortcut_settingUpdated() {
+ mockManageAccessibilityGranted(mTestableContext);
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ true,
+ UserShortcutType.TRIPLETAP,
+ List.of(TARGET_MAGNIFICATION),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(
+ Settings.Secure.getInt(
+ mTestableContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
+ AccessibilityUtils.State.OFF)
+ ).isEqualTo(AccessibilityUtils.State.ON);
+ }
+
+ @Test
+ public void enableShortcutsForTargets_disableTripleTapShortcut_settingUpdated() {
+ enableShortcutsForTargets_enableTripleTapShortcut_settingUpdated();
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ false,
+ UserShortcutType.TRIPLETAP,
+ List.of(TARGET_MAGNIFICATION),
+ mA11yms.getCurrentUserIdLocked());
+
+ assertThat(
+ Settings.Secure.getInt(
+ mTestableContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
+ AccessibilityUtils.State.OFF)
+ ).isEqualTo(AccessibilityUtils.State.OFF);
+ }
+
+ @Test
+ public void enableShortcutsForTargets_enableMultiFingerMultiTapsShortcut_settingUpdated() {
+ mockManageAccessibilityGranted(mTestableContext);
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ true,
+ UserShortcutType.TWOFINGER_DOUBLETAP,
+ List.of(TARGET_MAGNIFICATION),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(
+ Settings.Secure.getInt(
+ mTestableContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED,
+ AccessibilityUtils.State.OFF)
+ ).isEqualTo(AccessibilityUtils.State.ON);
+ }
+
+ @Test
+ public void enableShortcutsForTargets_disableMultiFingerMultiTapsShortcut_settingUpdated() {
+ enableShortcutsForTargets_enableMultiFingerMultiTapsShortcut_settingUpdated();
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ false,
+ UserShortcutType.TWOFINGER_DOUBLETAP,
+ List.of(TARGET_MAGNIFICATION),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(
+ Settings.Secure.getInt(
+ mTestableContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED,
+ AccessibilityUtils.State.OFF)
+ ).isEqualTo(AccessibilityUtils.State.OFF);
+ }
+
+ @Test
+ public void enableShortcutsForTargets_enableVolumeKeysShortcut_shortcutSet() {
+ mockManageAccessibilityGranted(mTestableContext);
+ setupShortcutTargetServices();
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ true,
+ UserShortcutType.HARDWARE,
+ List.of(TARGET_STANDARD_A11Y_SERVICE.flattenToString()),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(
+ ShortcutUtils.isComponentIdExistingInSettings(
+ mTestableContext, ShortcutConstants.UserShortcutType.HARDWARE,
+ TARGET_STANDARD_A11Y_SERVICE.flattenToString())
+ ).isTrue();
+ }
+
+ @Test
+ public void enableShortcutsForTargets_disableVolumeKeysShortcut_shortcutNotSet() {
+ enableShortcutsForTargets_enableVolumeKeysShortcut_shortcutSet();
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ false,
+ UserShortcutType.HARDWARE,
+ List.of(TARGET_STANDARD_A11Y_SERVICE.flattenToString()),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(
+ ShortcutUtils.isComponentIdExistingInSettings(
+ mTestableContext, ShortcutConstants.UserShortcutType.HARDWARE,
+ TARGET_STANDARD_A11Y_SERVICE.flattenToString())
+ ).isFalse();
+ }
+
+ @Test
+ public void enableShortcutsForTargets_enableQuickSettings_shortcutSet() {
+ mockManageAccessibilityGranted(mTestableContext);
+ setupShortcutTargetServices();
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ true,
+ UserShortcutType.QUICK_SETTINGS,
+ List.of(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(
+ ShortcutUtils.isComponentIdExistingInSettings(
+ mTestableContext, UserShortcutType.QUICK_SETTINGS,
+ TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString())
+ ).isTrue();
+ verify(mStatusBarManagerInternal)
+ .addQsTileToFrontOrEnd(
+ new ComponentName(
+ TARGET_ALWAYS_ON_A11Y_SERVICE.getPackageName(),
+ TARGET_ALWAYS_ON_A11Y_SERVICE_TILE_CLASS),
+ /* end= */ true);
+ }
+
+ @Test
+ public void enableShortcutsForTargets_disableQuickSettings_shortcutNotSet() {
+ enableShortcutsForTargets_enableQuickSettings_shortcutSet();
+
+ mA11yms.enableShortcutsForTargets(
+ /* enable= */ false,
+ UserShortcutType.QUICK_SETTINGS,
+ List.of(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()),
+ mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ assertThat(
+ ShortcutUtils.isComponentIdExistingInSettings(
+ mTestableContext, UserShortcutType.QUICK_SETTINGS,
+ TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString())
+ ).isFalse();
+ verify(mStatusBarManagerInternal)
+ .removeQsTile(
+ new ComponentName(
+ TARGET_ALWAYS_ON_A11Y_SERVICE.getPackageName(),
+ TARGET_ALWAYS_ON_A11Y_SERVICE_TILE_CLASS));
+ }
+
+ @Test
+ public void getA11yFeatureToTileMap_permissionNotGranted_throwsException() {
+ mTestableContext.getTestablePermissions().setPermission(
+ Manifest.permission.MANAGE_ACCESSIBILITY, PackageManager.PERMISSION_DENIED);
+
+ assertThrows(SecurityException.class,
+ () -> mA11yms.getA11yFeatureToTileMap(mA11yms.getCurrentUserIdLocked()));
+ }
+
+ @Test
+ public void getA11yFeatureToTileMap() {
+ mockManageAccessibilityGranted(mTestableContext);
+ setupShortcutTargetServices();
+
+ Bundle bundle = mA11yms.getA11yFeatureToTileMap(mA11yms.getCurrentUserIdLocked());
+
+ // Framework tile size + TARGET_ALWAYS_ON_A11Y_SERVICE_TILE_CLASS
+ assertThat(bundle.size())
+ .isEqualTo(ShortcutConstants.A11Y_FEATURE_TO_FRAMEWORK_TILE.size() + 1);
+ assertThat(
+ bundle.getParcelable(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString(),
+ ComponentName.class)
+ ).isEqualTo(
+ new ComponentName(
+ TARGET_ALWAYS_ON_A11Y_SERVICE.getPackageName(),
+ TARGET_ALWAYS_ON_A11Y_SERVICE_TILE_CLASS));
+ for (Map.Entry<ComponentName, ComponentName> entry :
+ ShortcutConstants.A11Y_FEATURE_TO_FRAMEWORK_TILE.entrySet()) {
+ assertThat(bundle.getParcelable(entry.getKey().flattenToString(), ComponentName.class))
+ .isEqualTo(entry.getValue());
+ }
+ }
+
private static AccessibilityServiceInfo mockAccessibilityServiceInfo(
ComponentName componentName) {
- return mockAccessibilityServiceInfo(componentName, false);
+ return mockAccessibilityServiceInfo(
+ componentName, /* isSystemApp= */ false, /* isAlwaysOnService=*/ false);
}
private static AccessibilityServiceInfo mockAccessibilityServiceInfo(
ComponentName componentName,
- boolean isSystemApp) {
+ boolean isSystemApp, boolean isAlwaysOnService) {
AccessibilityServiceInfo accessibilityServiceInfo =
Mockito.spy(new AccessibilityServiceInfo());
accessibilityServiceInfo.setComponentName(componentName);
@@ -941,7 +1334,15 @@
when(accessibilityServiceInfo.getResolveInfo()).thenReturn(mockResolveInfo);
mockResolveInfo.serviceInfo = Mockito.mock(ServiceInfo.class);
mockResolveInfo.serviceInfo.applicationInfo = Mockito.mock(ApplicationInfo.class);
+ mockResolveInfo.serviceInfo.packageName = componentName.getPackageName();
+ mockResolveInfo.serviceInfo.name = componentName.getClassName();
when(mockResolveInfo.serviceInfo.applicationInfo.isSystemApp()).thenReturn(isSystemApp);
+ if (isAlwaysOnService) {
+ accessibilityServiceInfo.flags |=
+ AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
+ mockResolveInfo.serviceInfo.applicationInfo.targetSdkVersion =
+ Build.VERSION_CODES.R;
+ }
return accessibilityServiceInfo;
}
@@ -974,6 +1375,22 @@
Intent.EXTRA_COMPONENT_NAME)).isEqualTo(componentName);
}
+ private void setupShortcutTargetServices() {
+ AccessibilityServiceInfo alwaysOnServiceInfo = mockAccessibilityServiceInfo(
+ TARGET_ALWAYS_ON_A11Y_SERVICE,
+ /* isSystemApp= */ false,
+ /* isAlwaysOnService= */ true);
+ when(alwaysOnServiceInfo.getTileServiceName())
+ .thenReturn(TARGET_ALWAYS_ON_A11Y_SERVICE_TILE_CLASS);
+ AccessibilityServiceInfo standardServiceInfo = mockAccessibilityServiceInfo(
+ TARGET_STANDARD_A11Y_SERVICE,
+ /* isSystemApp= */ false,
+ /* isAlwaysOnService= */ false);
+ mA11yms.getCurrentUserState().mInstalledServices.addAll(
+ List.of(alwaysOnServiceInfo, standardServiceInfo));
+ mA11yms.getCurrentUserState().updateTileServiceMapForAccessibilityServiceLocked();
+ }
+
public static class FakeInputFilter extends AccessibilityInputFilter {
FakeInputFilter(Context context,
AccessibilityManagerService service) {
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 ea1a68a..7891661 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 @@
@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 b705077..733f056 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.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 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 @@
@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 */);
- // 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 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());
- 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()};
+ // A device state that is not reported as being supported for the default test provider.
+ private static final DeviceState UNSUPPORTED_DEVICE_STATE = new DeviceState(
+ new DeviceState.Configuration.Builder(255, "UNSUPPORTED")
+ .build());
+
+ 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 @@
@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 @@
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 @@
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 @@
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 @@
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 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
});
}
- 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 @@
* @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 @@
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 @@
}
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 cfdb586..637bf03 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 @@
@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/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 1249707..67b131f 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -206,6 +206,7 @@
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
@@ -2150,12 +2151,14 @@
assertFalse(mService.isUidNetworkingBlocked(UID_E, false));
}
+ @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testBackgroundChainEnabled() throws Exception {
verify(mNetworkManager).setFirewallChainEnabled(FIREWALL_CHAIN_BACKGROUND, true);
}
+ @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testBackgroundChainOnProcStateChange() throws Exception {
@@ -2185,6 +2188,7 @@
assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
}
+ @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testBackgroundChainOnAllowlistChange() throws Exception {
@@ -2223,6 +2227,7 @@
assertFalse(mService.isUidNetworkingBlocked(UID_B, false));
}
+ @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testBackgroundChainOnTempAllowlistChange() throws Exception {
@@ -2261,6 +2266,7 @@
&& uidState.procState == procState && uidState.capability == capability;
}
+ @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testUidObserverFiltersProcStateChanges() throws Exception {
@@ -2323,6 +2329,7 @@
waitForUidEventHandlerIdle();
}
+ @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testUidObserverFiltersStaleChanges() throws Exception {
@@ -2343,6 +2350,7 @@
waitForUidEventHandlerIdle();
}
+ @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testUidObserverFiltersCapabilityChanges() throws Exception {
@@ -2422,6 +2430,7 @@
assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
}
+ @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testObsoleteHandleUidChanged() throws Exception {
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 16909ab..fad10f7 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.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 @@
* 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 @@
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 @@
}
@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 @@
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 @@
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 @@
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 @@
+ " <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 @@
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 @@
}
@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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 03f2749..26cda65 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 @@
// 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 @@
// 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 d6ac517..8cbcc22 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 @@
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 @@
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 45a2ba4..daa5a5a 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 @@
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 99d354a..b11f9b2 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 @@
@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 32b3558..da437c4 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.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 @@
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 @@
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 ce890f6..ff7129c 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.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 @@
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 @@
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 @@
// 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 @@
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 @@
}
@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/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index a58cf5f..dc504ca 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -152,6 +152,9 @@
public static final boolean ENABLE_TIME_CHANGE_CORRECTION
= SystemProperties.getBoolean("persist.debug.time_correction", true);
+ private static final boolean USE_DEDICATED_HANDLER_THREAD =
+ SystemProperties.getBoolean("persist.debug.use_dedicated_handler_thread", false);
+
static final boolean DEBUG = false; // Never submit with true
static final boolean DEBUG_RESPONSE_STATS = DEBUG || Log.isLoggable(TAG, Log.DEBUG);
static final boolean COMPRESS_TIME = false;
@@ -404,11 +407,11 @@
IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED);
filter.addAction(Intent.ACTION_USER_STARTED);
getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, filter,
- null, /* scheduler= */ Flags.useDedicatedHandlerThread() ? mHandler : null);
+ null, /* scheduler= */ USE_DEDICATED_HANDLER_THREAD ? mHandler : null);
getContext().registerReceiverAsUser(new UidRemovedReceiver(), UserHandle.ALL,
new IntentFilter(ACTION_UID_REMOVED), null,
- /* scheduler= */ Flags.useDedicatedHandlerThread() ? mHandler : null);
+ /* scheduler= */ USE_DEDICATED_HANDLER_THREAD ? mHandler : null);
mRealTimeSnapshot = SystemClock.elapsedRealtime();
mSystemTimeSnapshot = System.currentTimeMillis();
@@ -497,7 +500,7 @@
}
private Handler getUsageEventProcessingHandler() {
- if (Flags.useDedicatedHandlerThread()) {
+ if (USE_DEDICATED_HANDLER_THREAD) {
return new H(UsageStatsHandlerThread.get().getLooper());
} else {
return new H(BackgroundThread.get().getLooper());
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 5a52968..ae4faa8 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.voiceinteraction;
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
@@ -1072,8 +1073,10 @@
// If visEnabledKey is set to true (or absent), we try following VIS path.
String csPkgName = mContext.getResources()
.getString(R.string.config_defaultContextualSearchPackageName);
- if (!csPkgName.equals(getCurInteractor(
- Binder.getCallingUserHandle().getIdentifier()).getPackageName())) {
+ ComponentName currInteractor =
+ getCurInteractor(Binder.getCallingUserHandle().getIdentifier());
+ if (currInteractor == null
+ || !csPkgName.equals(currInteractor.getPackageName())) {
// Check if the interactor can handle Contextual Search.
// If not, return failure.
Slog.w(TAG, "Contextual Search not supported yet. Returning failure.");
@@ -2718,7 +2721,7 @@
}
launchIntent.setComponent(resolveInfo.getComponentInfo().getComponentName());
launchIntent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NO_ANIMATION
- | FLAG_ACTIVITY_NO_USER_ACTION);
+ | FLAG_ACTIVITY_NO_USER_ACTION | FLAG_ACTIVITY_CLEAR_TASK);
launchIntent.putExtras(args);
boolean isAssistDataAllowed = mAtmInternal.isAssistDataAllowed();
final List<ActivityAssistInfo> records = mAtmInternal.getTopVisibleActivities();
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 048b1b2..ff4be55 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -2797,7 +2797,9 @@
/**
* 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 @@
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 302a472..112471b 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -401,7 +401,7 @@
* @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 2150b5d..d3a50bb 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -10258,6 +10258,31 @@
@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 @@
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 88acbab..a047b97 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -18852,7 +18852,7 @@
*/
@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 17f91eb..060015b 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 @@
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
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
index 78f277e..f70a17d 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
@@ -1051,6 +1051,9 @@
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 name Ljava/lang/String;
+ MethodParameters:
+ Name Flags
+ <no name> mandated
private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
@@ -1074,6 +1077,12 @@
0 18 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
0 18 3 longName Ljava/lang/String;
0 18 4 shortName Ljava/lang/String;
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
+ <no name>
+ <no name>
Signature: #x // (Ljava/lang/String;Ljava/lang/String;)V
RuntimeInvisibleAnnotations:
x: #x()
@@ -1224,6 +1233,9 @@
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 name Ljava/lang/String;
+ MethodParameters:
+ Name Flags
+ <no name> mandated
private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
descriptor: (Ljava/lang/String;I)V
@@ -1239,6 +1251,10 @@
LocalVariableTable:
Start Length Slot Name Signature
0 7 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
Signature: #x // ()V
private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
@@ -2031,6 +2047,9 @@
Start Length Slot Name Signature
0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
0 10 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
public java.lang.Integer get();
descriptor: ()Ljava/lang/Integer;
@@ -2147,6 +2166,9 @@
Start Length Slot Name Signature
0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
0 10 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
public java.lang.Integer get();
descriptor: ()Ljava/lang/Integer;
@@ -2304,6 +2326,9 @@
Start Length Slot Name Signature
0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass;
0 15 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
}
SourceFile: "TinyFrameworkNestedClasses.java"
RuntimeInvisibleAnnotations:
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt
index 406cb74..37de857 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt
@@ -795,6 +795,9 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> mandated
private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
@@ -815,6 +818,12 @@
RuntimeInvisibleAnnotations:
x: #x()
android.hosttest.annotation.HostSideTestStub
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
+ <no name>
+ <no name>
public java.lang.String getLongName();
descriptor: ()Ljava/lang/String;
@@ -969,6 +978,9 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> mandated
private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
descriptor: (Ljava/lang/String;I)V
@@ -986,6 +998,10 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
@@ -1769,6 +1785,9 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
}
InnerClasses:
public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt
index c673262..c9c607c 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt
@@ -1225,6 +1225,9 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> mandated
private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
@@ -1257,6 +1260,12 @@
RuntimeInvisibleAnnotations:
x: #x()
android.hosttest.annotation.HostSideTestStub
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
+ <no name>
+ <no name>
public java.lang.String getLongName();
descriptor: ()Ljava/lang/String;
@@ -1453,6 +1462,9 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> mandated
private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
descriptor: (Ljava/lang/String;I)V
@@ -1474,6 +1486,10 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
@@ -2578,6 +2594,9 @@
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
public java.lang.Integer get();
descriptor: ()Ljava/lang/Integer;
@@ -2745,6 +2764,9 @@
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
public java.lang.Integer get();
descriptor: ()Ljava/lang/Integer;
@@ -2977,6 +2999,9 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
}
InnerClasses:
public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
index 406cb74..37de857 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
@@ -795,6 +795,9 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> mandated
private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
@@ -815,6 +818,12 @@
RuntimeInvisibleAnnotations:
x: #x()
android.hosttest.annotation.HostSideTestStub
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
+ <no name>
+ <no name>
public java.lang.String getLongName();
descriptor: ()Ljava/lang/String;
@@ -969,6 +978,9 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> mandated
private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
descriptor: (Ljava/lang/String;I)V
@@ -986,6 +998,10 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
@@ -1769,6 +1785,9 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
}
InnerClasses:
public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
index 4fd5701..a57907d 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
@@ -1532,6 +1532,9 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> mandated
private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
@@ -1569,6 +1572,12 @@
RuntimeInvisibleAnnotations:
x: #x()
android.hosttest.annotation.HostSideTestStub
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
+ <no name>
+ <no name>
public java.lang.String getLongName();
descriptor: ()Ljava/lang/String;
@@ -1798,6 +1807,9 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> mandated
private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
descriptor: (Ljava/lang/String;I)V
@@ -1824,6 +1836,10 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
@@ -3190,6 +3206,9 @@
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
public java.lang.Integer get();
descriptor: ()Ljava/lang/Integer;
@@ -3407,6 +3426,9 @@
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
public java.lang.Integer get();
descriptor: ()Ljava/lang/Integer;
@@ -3704,6 +3726,9 @@
com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
}
InnerClasses:
public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses